January 2020
« Nov    


WordPress Quotes

Every artist was first an amateur.
Ralph Waldo Emerson
January 2020
« Nov    

Short Cuts

2012 SERVER (64)
2016 windows (9)
AIX (13)
Amazon (40)
Ansibile (19)
Apache (135)
Asterisk (2)
cassandra (2)
Centos (211)
Centos RHEL 7 (268)
chef (3)
cloud (2)
cluster (3)
Coherence (1)
DB2 (5)
DISK (25)
DNS (9)
Docker (30)
Eassy (11)
ELKS (1)
Fedora (6)
ftp (5)
GIT (3)
GOD (2)
Grub (1)
Hacking (10)
Hadoop (6)
health (2)
horoscope (23)
Hyper-V (10)
IIS (15)
JAVA (7)
JBOSS (32)
jenkins (1)
Kubernetes (7)
Ldap (5)
Linux (188)
Linux Commands (166)
Load balancer (5)
mariadb (14)
Mongodb (4)
MQ Server (24)
MYSQL (84)
Nagios (5)
NaturalOil (13)
Nginx (35)
Ngix (1)
openldap (1)
Openstack (6)
Oracle (35)
Perl (3)
Postfix (19)
Postgresql (1)
PowerShell (2)
Python (3)
qmail (36)
Redis (12)
RHCE (28)
Security on Centos (29)
SFTP (1)
Shell (64)
Solaris (58)
Sql Server 2012 (4)
squid (3)
SSH (10)
SSL (14)
Storage (1)
swap (3)
TIPS on Linux (28)
tomcat (62)
Ubuntu (1)
Uncategorized (30)
Veritas (2)
vfabric (1)
VMware (28)
Weblogic (38)
Websphere (71)
Windows (19)
Windows Software (2)
wordpress (1)

WP Cumulus Flash tag cloud by Roy Tanck requires Flash Player 9 or better.

Who's Online

12 visitors online now
1 guests, 11 bots, 0 members

Hit Counter provided by dental implants orange county

Docker installation builds Tomcat + MySQL

Docker installation builds Tomcat + MySQL

virtual machine
Virtual machine installation Docker
Build on a clean CentOS image
Centos image preparation
Pull the Centos image on the virtual machine: docker pull centos
Create a container to run the Centos image: docker run -it -d –name mycentos centos /bin/bash
Note: There is an error here [ WARNING: IPv4 forwarding is disabled. Networking will not work. ]

Change the virtual machine file: vim /usr/lib/sysctl.d/00-system.conf
Add the following content
Restart the network: systemctl restart network
Note: There is another problem here, systemctl in docker can not be used normally. Find the following solutions on the official website

Link: https://forums.docker.com/t/systemctl-status-is-not-working-in-my-docker-container/9075/4

Run mirror with the following statement
docker run –privileged -v /sys/fs/cgroup:/sys/fs/cgroup -it -d –name usr_sbin_init_centos centos /usr/sbin/init

1. Must have –privileged

2. Must have -v /sys/fs/cgroup:/sys/fs/cgroup

3. Replace bin/bash with /usr/sbin/init

Finally, I was able to run a Centos image.

Install the JAVA environment
Prepare the JDK tarball to upload to the virtual machine
Put the tarball into the docker container using docker cp
docker cp jdk-11.0.2_linux-x64_bin.tar.gz 41dbc0fbdf3c:/

The same as the linux cp specified usage, you need to add the identifier of the container: id or name

Extract the tar package
tar -xf jdk-11.0.2_linux-x64_bin.tar.gz -C /usr/local/java/jdk
Edit profile file export java environment variable


export JAVA_HOME=/usr/local/java/jdk/jdk1.8.0_91
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
Run source /etc/profile to make environment variables take effect
Whether the test is successful
java –version


java 11.0.2 2019-01-15 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.2+9-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.2+9-LTS, mixed mode)
Install Tomcat
Prepare the tomcat tar package to upload to the virtual machine and cp to the docker container
Extract to
tar -xf apache-tomcat-8.5.38.tar.gz -C /usr/local/tomcat
Set boot boot, by using rc.local file

rc.local Add the following code

export JAVA_HOME=/usr/local/java/jdk/jdk-11.0.2
Open tomcat
/usr/local/tomcat/apache-tomcat-8.5.38/bin/ directory running
curl localhost:8080

Install mysql
Get the yum source of mysql
wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm
Install the above yum source
yum -y install mysql57-community-release-el7-10.noarch.rpm
Yum install mysql
yum -y install mysql-community-server
Change the mysql configuration: /etc/my/cnf
Validate_password=OFF # Turn off password verification
Initialize specified but the data directory has files in it # The default behavior of timestamp from 5.6 is already deprecated, need to close the warning


Get the mysql initial password
grep “password” /var/log/mysqld.log

[Note] A temporary password is generated for root@localhost: k:nT<dT,t4sF

Use this password to log in to mysql

Go to mysql and proceed


mysql -u root -p

change the password

ALTER USER ‘root’@’localhost’ IDENTIFIED BY ‘111111’;

Change to make mysql remote access

update user set host = ‘%’ where user = ‘root’;
Test, you can use physical machine, use navicat to access mysql in docker
Packing container
On the docker hub

Submit the container as a mirror

docker commit -a ‘kane’ -m ‘test’ container_id images_name:images_tag

docker push kane0725/tomcat
Local tarball everywhere

Export to cost tar package

docker export -o test.tar a404c6c174a2

Import the tar package into a mirror

docker import test.tar test_images
Use Dockerfile
Note: only build a mirror of tomcat

Ready to work
Create a special folder and put the jdk and tomcat tarballs
Create a Dockerfile in this directory
Centos base image
document content
FROM centos
MAINTAINER tomcat mysql
ADD jdk-11.0.2 /usr/local/java
ENV JAVA_HOME /usr/local/java/
ADD apache-tomcat-8.5.38 /usr/local/tomcat8
Output results using docker build

[root@localhost dockerfile]

# docker build -t tomcats:centos .
Sending build context to Docker daemon 505.8 MB
Step 1/7 : FROM centos
—> 1e1148e4cc2c
Step 2/7 : MAINTAINER tomcat mysql
—> Using cache
—> 889454b28f55
Step 3/7 : ADD jdk-11.0.2 /usr/local/java
—> Using cache
—> 8cad86ae7723
Step 4/7 : ENV JAVA_HOME /usr/local/java/
—> Running in 15d89d66adb4
—> 767983acfaca
Removing intermediate container 15d89d66adb4
Step 5/7 : ADD apache-tomcat-8.5.38 /usr/local/tomcat8
—> 4219d7d611ec
Removing intermediate container 3c2438ecf955
Step 6/7 : EXPOSE 8080
—> Running in 56c4e0c3b326
—> 7c5bd484168a
Removing intermediate container 56c4e0c3b326
Step 7/7 : RUN /usr/local/tomcat8/bin/startup.sh
—> Running in 7a73d0317db3

Tomcat started.
—> b53a6d54bf64
Removing intermediate container 7a73d0317db3
Successfully built b53a6d54bf64
Docker build problem
Be sure to bring the order behind. Otherwise it will report an error.
“docker build” requires exactly 1 argument(s).
Run a container

docker run -it –name tomcats –restart always -p 1234:8080 tomcats /bin/bash

tomcat startup.sh



Using CATALINA_BASE: /usr/local/tomcat8
Using CATALINA_HOME: /usr/local/tomcat8
Using CATALINA_TMPDIR: /usr/local/tomcat8/temp
Using JRE_HOME: /usr/local/java/
Using CLASSPATH: /usr/local/tomcat8/bin/bootstrap.jar:/usr/local/tomcat8/bin/tomcat-juli.jar
Tomcat started.
Use docker compose
Install docker compose
Official: https://docs.docker.com/compose/install/

The way I choose is pip installation


pip install docker-compose

docker-compose –version


docker-compose version 1.23.2, build 1110ad0
Write docker-compose.yml

This yml file builds a mysql a tomcat container

version: “3”
container_name: mysql
image: mysql:5.7
restart: always
– ./mysql/data/:/var/lib/mysql/
– ./mysql/conf/:/etc/mysql/mysql.conf.d/
– “6033:3306”
container_name: tomcat
restart: always
image: tomcat
– 8080:8080
– 8009:8009
– mysql:m1 #Connect to database mirroring

Volumn must be a path, you cannot specify a file

Tomcat specifies that the external conf has been created unsuccessfully, do not know why, prompt

tomcat | Feb 20, 2019 2:23:29 AM org.apache.catalina.startup.Catalina load
tomcat | WARNING: Unable to load server configuration from [/usr/local/tomcat/conf/server.xml]
tomcat | Feb 20, 2019 2:23:29 AM org.apache.catalina.startup.Catalina start
tomcat | SEVERE: Cannot start server. Server instance is not configured.
tomcat exited with code 1
Run command
Note: Must be executed under the directory of the yml file

docker-compose up -d

———-View docker container——-

[root@localhost docker-compose]

# docker ps -a
1a8a0165a3a8 tomcat “catalina.sh run” 7 seconds ago Up 6 seconds>8009/tcp,>8080/tcp tomcat
ddf081e87d67 mysql:5.7 “docker-entrypoint…” 7 seconds ago Up 7 seconds 33060/tcp, 0

Kubernetes install centos7

Kubeadm quickly builds a k8s cluster


Master01: (minimum 2 core CPU)



Services network:

Pod network:

  1. Configure hosts to resolve each host

vim /etc/hosts localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 master01 node01

  1. Synchronize each host time

yum install -y ntpdate
ntpdate time.windows.com

14 Mar 16:51:32 ntpdate[46363]: adjust time server offset -0.001108 sec

  1. Close SWAP and close selinux

swapoff -a

vim /etc/selinux/config

This file controls the state of SELinux on the system.

SELINUX= can take one of these three values:

enforcing – SELinux security policy is enforced.

permissive – SELinux prints warnings instead of enforcing.

disabled – No SELinux policy is loaded.


  1. Install docker-ce

yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager –add-repo http://mirrors.aliyun.com/docker-ce/linux/CentOS/docker-ce.repo
yum makecache fast
yum -y install docker-ce

Appears after Docker installation: WARNING: bridge-nf-call-iptables is disabled

vim /etc/sysctl.conf

sysctl settings are defined through files in

/usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.

Vendors settings live in /usr/lib/sysctl.d/.

To override a whole file, create a new file with the same in

/etc/sysctl.d/ and put new settings there. To override

only specific settings, add a file with a lexically later

name in /etc/sysctl.d/ and put new settings there.


For more information, see sysctl.conf(5) and sysctl.d(5).


systemctl enable docker && systemctl start docker

  1. Install kubernetes

cat < /etc/yum.repos.d/kubernetes.repo


gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
setenforce 0
yum install -y kubelet kubeadm kubectl
systemctl enable kubelet && systemctl start kubelet

  1. Initialize the cluster

kubeadm init –image-repository registry.aliyuncs.com/google_containers –cubernetes-version v1.13.1 –pod-network-cidr = / 16

Your Kubernetes master has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run “kubectl apply -f [podnetwork].yaml” with one of the options listed at:

You can now join any number of machines by running the following on each node
as root:

kubeadm join –token wgrs62.vy0trlpuwtm5jd75 –discovery-token-ca-cert-hash sha256:6e947e63b176acf976899483d41148609a6e109067ed6970b9fbca8d9261c8d0

  1. Manually deploy flannel

Flannel URL: https://github.com/coreos/flannel

for Kubernetes v1.7 +

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

podsecuritypolicy.extensions/psp.flannel.unprivileged created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.extensions/kube-flannel-ds-amd64 created
daemonset.extensions/kube-flannel-ds-arm64 created
daemonset.extensions/kube-flannel-ds-arm created
daemonset.extensions/kube-flannel-ds-ppc64le created
daemonset.extensions/kube-flannel-ds-s390x created

8.node placement

Install docker kubelet kubeadm

Docker installation is the same as step 4, kubelet kubeadm installation is the same as step 5

9.node joins the master

kubeadm join –token wgrs62.vy0trlpuwtm5jd75 –discovery-token-ca-cert-hash sha256:6e947e63b176acf976899483d41148609a6e109067ed6970b9fbca8d9261c8d0

Kubectl get nodes #View node status

localhost.localdomain NotReady 130m v1.13.4
master01 Ready master 4h47m v1.13.4
node01 Ready 94m v1.13.4

Kubectl get cs #View component status

scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {“health”: “true”}

Kubectl get ns #View namespace

default Active 4h41m
kube-public Active 4h41m
kube-system Active 4h41m

Kubectl get pods -n kube-system #View pod status

coredns-78d4cf999f-bszbk 1/1 Running 0 4h44m
coredns-78d4cf999f-j68hb 1/1 Running 0 4h44m
etcd-master01 1/1 Running 0 4h43m
kube-apiserver-master01 1/1 Running 1 4h43m
kube-controller-manager-master01 1/1 Running 2 4h43m
kube-flannel-ds-amd64-27×59 1/1 Running 1 126m
kube-flannel-ds-amd64-5sxgk 1/1 Running 0 140m
kube-flannel-ds-amd64-xvrbw 1/1 Running 0 91m
kube-proxy-4pbdf 1/1 Running 0 91m
kube-proxy-9fmrl 1/1 Running 0 4h44m
kube-proxy-nwkl9 1/1 Running 0 126m
kube-scheduler-master01 1/1 Running 2 4h43m

Environment preparation master01 node01 node02, connect to the network, modify the hosts file, and confirm that the three hosts resolve each other.

Vim /etc/hosts localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 master01 node01 node02

Host configuration Ali YUM source

mv /etc/yum.repos.d/ CentOS -Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup && curl -o /etc/yum.repos.d/CentOS-Base.repo http ://mirrors.aliyun.com/repo/Centos-7.repo

Start deploying kubernetes

  1. Install etcd on master01

Yum install etcd -y

After the installation is complete, modify the etcd configuration file /etc/etcd/etcd.conf

Vim /etc/etcd/etcd.conf


Modify the listening address ETCD_LISTEN_CLIENT_URLS=”″ #Modify the etcd address as the local address

Set service startup

Systemctl start etcd && systemctl enable etcd

  1. Install kubernetes on all hosts

Yum install kubernetes -y

  1. Configure the master

Vim /etc/kubernetes/config

KUBE_MASTER=”–master=″ #Modify kube_master address

Vim /etc/kubernetes/apiserver


Modify the listening address KUBE_ETCD_SERVERS=”–etcd-servers=″ #Modify the etcd address

KUBE_ADMISSION_CONTROL=”–admission-control =NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota” #Delete authentication parameter ServiceAccount

Set the service startup, start sequence apiserver>scheduler=controller-manager

Systemctl start docker && systemctl enable docker
systemctl start kube-apiserver && systemctl enable kube-apiserver
systemctl start kube-scheduler && systemctl enable kube-scheduler
systemctl start kube-controller-manager && systemctl enable kube-controller-manager

  1. Configure node

Vim /etc/kubernetes/config

KUBE_MASTER=”–master=″ #Modify the master address

Vim /etc/kubernetes/kubelet

KUBELET_ADDRESS=”–address=″ #Modify kubelet address
KUBELET_HOSTNAME=”–hostname-override=″ #Modify kubelet hostname
KUBELET_API_SERVER=”–api-servers= 8080″ #Modify apiserver address

Set service startup

Systemctl start docker && systemctl enable docker
systemctl start kubelet && systemctl enable kubelet
systemctl start kube-proxy && systemctl enable kube-proxy

  1. Deployment is complete, check the cluster status

Kubectl get nodes

[root@node02 kubernetes]

# kubectl -s get nodes -o wide

  1. Install flannel on all hosts

Yum install flannel -y

Vim /etc/sysconfig/flanneld

FLANNEL_ETCD_ENDPOINTS=”″ #Modify the etcd address

Etcdctl mk /atomic.io/network/config ‘{ “Network”: “” }’ #Set the container network in the etcd host

Master host restart service

Systemctl start flanneld && systemctl enable flanneld
systemctl restart docker
systemctl restart kube-apiserver
systemctl restart kube-scheduler
systemctl restart kube-controller-manager

Node host restart service

Systemctl start flanneld && systemctl enable flanneld
systemctl restart docker
systemctl restart kubelet
systemctl restart kube-proxy

pyenv + pyenv-virtualenv (CentOS 7)

I summarized the installation on CentOS.
Although it is little different from OSX, it is organized because the premise environment is different.

I am trying in the next environment.

$ uname -r
$ lsb_release -a
LSB Version: :core-4.1-amd64:core-4.1-noarch:cxx-4.1-amd64:cxx-4.1-noarch:desktop-4.1-amd64:desktop-4.1-noarch:languages-4.1-amd64:languages-4.1-noarch:printing-4.1-amd64:printing-4.1-noarch
Distributor ID: CentOS
Description: CentOS Linux release 7.1.1503 (Core)
Release: 7.1.1503
Codename: Core

Installing packages

Installation of packages required for CentOS

yum -y install git
yum -y groupinstall “Development Tools”
yum -y install readline-devel zlib-devel bzip2-devel sqlite-devel openssl-devel

Installation of pyenv

git clone https://github.com/yyuu/pyenv.git ~/.pyenv
echo ‘export PYENV_ROOT=”$HOME/.pyenv”‘ >> ~/.bash_profile
echo ‘export PATH=”$PYENV_ROOT/bin:$PATH”‘ >> ~/.bash_profile
echo ‘eval “$(pyenv init -)”‘ >> ~/.bash_profile
source ~/.bash_profile
exec $SHELL -l


git clone https://github.com/yyuu/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv
echo ‘eval “$(pyenv virtualenv-init -)”‘ >> ~/.bash_profile
exec $SHELL -l

How to use pyenv

List of installable distributions, versions

pyenv install 2.7.10
pyenv install 3.5.0


Installation of the version you want to use

$ pyenv versions

  • system (set by /home/saitou/.pyenv/version)

Changing the version to be used by default

Do not make changes to Python on the system side.
In the following, 2.7.10 which was additionally installed is changed to the default of the user environment.

pyenv global 2.7.10
pip install – U pip
If you want to use Python on the system side, specify system.

$ python -V
Python 2.7.5
$ pyenv global 2.7.10
$ python -V
Python 2.7.10
$ pyenv global system
$ python -V
Python 2.7.5

How to use pyenv + pyenv-virtualenv

pyenv virtualenv

I want to use different versions for each project.
In this way you can allocate specific directories to specific versions and use them separately.

$ pyenv virtualenv 3.5.0 new_env
$ mkdir -p work/new_project && work/new_project/
$ pyenv versions

  • system (set by /home/saitou/.pyenv/version)
    $ pyenv local new_env
    pyenv-virtualenv: activate new_env
    $ python -V
    Python 3.5.0
    $ cd ..
    pyenv-virtualenv: deactivate new_env
    $ python -V
    Python 2.7.5
    $ cd new_project/
    pyenv-virtualenv: activate new_env
    $ python -V
    Python 3.5.0

Yellowdog Update Modified

Yum (Yellowdog Update Modified) is an RPM package management tool used on CentOS and RedHat systems. The yum history command allows the system administrator to roll back the system to the previous state, but due to some limitations, rollback is not possible in all cases Success, sometimes yum command may do nothing, and sometimes may delete some other packages.

I suggest that you still have to do a complete system backup before you upgrade, and yum history can not be used to replace the system backup. System backup allows you to restore the system to an arbitrary node status.

In some cases, what should I do if the installed application does not work or has some errors after it has been patched (possibly due to library incompatibilities or package upgrades)?

Talk to the application development team and find out where the problem is with libraries and packages, then use the yum history command to roll back.

Server patching is one of the important task of Linux system administrator to make the system more stable and better performance. All the vendors used to release security/vulnerabilities patches very often, the affected package must be updated in order to limit any potential security risks.

Yum (Yellowdog Update Modified) is RPM Package Management utility for CentOS and Red Hat systems, Yum history command allows administrator to rollback the system to a previous state but due to some limitations, rollbacks do not work in all situations, or The yum command may simply do nothing, or it may remove packages you do not expect.

I advise you to take a full system backup prior to performing any update/upgrade is always recommended, and yum history is NOT meant to replace systems backups. This will help you to restore the system to previous state at any point of time.

yum update
Loaded plugins: fastestmirror, security
Setting up Update Process
Loading mirror speeds from cached hostfile
epel/metalink | 12 kB 00:00

  • epel: mirror.csclub.uwaterloo.ca
    base | 3.7 kB 00:00
    dockerrepo | 2.9 kB 00:00
    draios | 2.9 kB 00:00
    draios/primary_db | 13 kB 00:00
    epel | 4.3 kB 00:00
    epel/primary_db | 5.9 MB 00:00
    extras | 3.4 kB 00:00
    updates | 3.4 kB 00:00
    updates/primary_db | 2.5 MB 00:00
    Resolving Dependencies
    –> Running transaction check
    —> Package git.x86_64 0:1.7.1-8.el6 will be updated
    —> Package git.x86_64 0:1.7.1-9.el6_9 will be an update
    —> Package httpd.x86_64 0:2.2.15-60.el6.centos.4 will be updated
    —> Package httpd.x86_64 0:2.2.15-60.el6.centos.5 will be an update
    —> Package httpd-tools.x86_64 0:2.2.15-60.el6.centos.4 will be updated
    —> Package httpd-tools.x86_64 0:2.2.15-60.el6.centos.5 will be an update
    —> Package perl-Git.noarch 0:1.7.1-8.el6 will be updated
    —> Package perl-Git.noarch 0:1.7.1-9.el6_9 will be an update
    –> Finished Dependency Resolution

Dependencies Resolved


Package Arch Version Repository Size

git x86_64 1.7.1-9.el6_9 updates 4.6 M
httpd x86_64 2.2.15-60.el6.centos.5 updates 836 k
httpd-tools x86_64 2.2.15-60.el6.centos.5 updates 80 k
perl-Git noarch 1.7.1-9.el6_9 updates 29 k

Transaction Summary

Upgrade 4 Package(s)

Total download size: 5.5 M
Is this ok [y/N]: n

As you can see in the above output git package update is available, so we are going to take that. Run the following command to know the version information about the package (current installed version and available update version).

yum list git
Loaded plugins: fastestmirror, security
Setting up Update Process
Loading mirror speeds from cached hostfile

  • epel: mirror.csclub.uwaterloo.ca
    Installed Packages
    git.x86_64 1.7.1-8.el6 @base
    Available Packages

Run the following command to update git package from 1.7.1-8 to 1.7.1-9.

yum update git

Loaded plugins: fastestmirror, presto
Setting up Update Process
Loading mirror speeds from cached hostfile

  • base: repos.lax.quadranet.com
  • epel: fedora.mirrors.pair.com
  • extras: mirrors.seas.harvard.edu
  • updates: mirror.sesp.northwestern.edu
    Resolving Dependencies
    –> Running transaction check
    —> Package git.x86_64 0:1.7.1-8.el6 will be updated
    –> Processing Dependency: git = 1.7.1-8.el6 for package: perl-Git-1.7.1-8.el6.noarch
    —> Package git.x86_64 0:1.7.1-9.el6_9 will be an update
    –> Running transaction check
    —> Package perl-Git.noarch 0:1.7.1-8.el6 will be updated
    —> Package perl-Git.noarch 0:1.7.1-9.el6_9 will be an update
    –> Finished Dependency Resolution

Dependencies Resolved


Package Arch Version Repository Size

git x86_64 1.7.1-9.el6_9 updates 4.6 M
Updating for dependencies:
perl-Git noarch 1.7.1-9.el6_9 updates 29 k

Transaction Summary

Upgrade 2 Package(s)

Total download size: 4.6 M
Is this ok [y/N]: y
Downloading Packages:
Setting up and reading Presto delta metadata
Processing delta metadata
Package(s) data still to download: 4.6 M
(1/2): git-1.7.1-9.el6_9.x86_64.rpm | 4.6 MB 00:00

(2/2): perl-Git-1.7.1-9.el6_9.noarch.rpm | 29 kB 00:00

Total 5.8 MB/s | 4.6 MB 00:00
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Updating : perl-Git-1.7.1-9.el6_9.noarch 1/4
Updating : git-1.7.1-9.el6_9.x86_64 2/4
Cleanup : perl-Git-1.7.1-8.el6.noarch 3/4
Cleanup : git-1.7.1-8.el6.x86_64 4/4
Verifying : git-1.7.1-9.el6_9.x86_64 1/4
Verifying : perl-Git-1.7.1-9.el6_9.noarch 2/4
Verifying : git-1.7.1-8.el6.x86_64 3/4
Verifying : perl-Git-1.7.1-8.el6.noarch 4/4

git.x86_64 0:1.7.1-9.el6_9

Dependency Updated:
perl-Git.noarch 0:1.7.1-9.el6_9


Verify updated version of git package.

yum list git

Installed Packages
git.x86_64 1.7.1-9.el6_9 @updates


rpm -q git


As of now, we have successfully completed package update and got a package for rollback. Just follow below steps for rollback mechanism.

First get the yum transaction id using following command. The below output clearly shows all the required information such transaction id, who done the transaction (i mean username), date and time, Actions (Install or update), how many packages altered in this transaction.

yum history


yum history list all

Loaded plugins: fastestmirror, presto

ID | Login user | Date and time | Action(s) | Altered

13 | root               | 2017-08-18 13:30 | Update         |    2
12 | root               | 2017-08-10 07:46 | Install        |    1
11 | root               | 2017-07-28 17:10 | E, I, U        |   28 EE
10 | root               | 2017-04-21 09:16 | E, I, U        |  162 EE
 9 | root               | 2017-02-09 17:09 | E, I, U        |   20 EE
 8 | root               | 2017-02-02 10:45 | Install        |    1
 7 | root               | 2016-12-15 06:48 | Update         |    1
 6 | root               | 2016-12-15 06:43 | Install        |    1
 5 | root               | 2016-12-02 10:28 | E, I, U        |   23 EE
 4 | root               | 2016-10-28 05:37 | E, I, U        |   13 EE
 3 | root               | 2016-10-18 12:53 | Install        |    1
 2 | root               | 2016-09-30 10:28 | E, I, U        |   31 EE
 1 | root               | 2016-07-26 11:40 | E, I, U        |  160 EE

The above command shows two packages has been altered because git updated it’s dependence package too perl-Git. Run the following command to view detailed information about the transaction.

yum history info 13

Loaded plugins: fastestmirror, presto
Transaction ID : 13
Begin time : Fri Aug 18 13:30:52 2017
Begin rpmdb : 420:f5c5f9184f44cf317de64d3a35199e894ad71188
End time : 13:30:54 2017 (2 seconds)
End rpmdb : 420:d04a95c25d4526ef87598f0dcaec66d3f99b98d4
User : root
Return-Code : Success
Command Line : update git
Transaction performed with:
Installed rpm-4.8.0-55.el6.x86_64 @base
Installed yum-3.2.29-81.el6.centos.noarch @base
Installed yum-plugin-fastestmirror-1.1.30-40.el6.noarch @base
Installed yum-presto-0.6.2-1.el6.noarch @anaconda-CentOS-201207061011.x86_64/6.3
Packages Altered:
Updated git-1.7.1-8.el6.x86_64 @base
Update 1.7.1-9.el6_9.x86_64 @updates
Updated perl-Git-1.7.1-8.el6.noarch @base
Update 1.7.1-9.el6_9.noarch @updates
history info

Fire the following command to Rollback the git package to the previous version.

yum history undo 13

Loaded plugins: fastestmirror, presto
Undoing transaction 53, from Fri Aug 18 13:30:52 2017
Updated git-1.7.1-8.el6.x86_64 @base
Update 1.7.1-9.el6_9.x86_64 @updates
Updated perl-Git-1.7.1-8.el6.noarch @base
Update 1.7.1-9.el6_9.noarch @updates
Loading mirror speeds from cached hostfile

  • base: repos.lax.quadranet.com
  • epel: fedora.mirrors.pair.com
  • extras: repo1.dal.innoscale.net
  • updates: mirror.vtti.vt.edu
    Resolving Dependencies
    –> Running transaction check
    —> Package git.x86_64 0:1.7.1-8.el6 will be a downgrade
    —> Package git.x86_64 0:1.7.1-9.el6_9 will be erased
    —> Package perl-Git.noarch 0:1.7.1-8.el6 will be a downgrade
    —> Package perl-Git.noarch 0:1.7.1-9.el6_9 will be erased
    –> Finished Dependency Resolution

Dependencies Resolved


Package Arch Version Repository Size

git x86_64 1.7.1-8.el6 base 4.6 M
perl-Git noarch 1.7.1-8.el6 base 29 k

Transaction Summary

Downgrade 2 Package(s)

Total download size: 4.6 M
Is this ok [y/N]: y
Downloading Packages:
Setting up and reading Presto delta metadata
Processing delta metadata
Package(s) data still to download: 4.6 M
(1/2): git-1.7.1-8.el6.x86_64.rpm | 4.6 MB 00:00

(2/2): perl-Git-1.7.1-8.el6.noarch.rpm | 29 kB 00:00

Total 3.4 MB/s | 4.6 MB 00:01
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : perl-Git-1.7.1-8.el6.noarch 1/4
Installing : git-1.7.1-8.el6.x86_64 2/4
Cleanup : perl-Git-1.7.1-9.el6_9.noarch 3/4
Cleanup : git-1.7.1-9.el6_9.x86_64 4/4
Verifying : git-1.7.1-8.el6.x86_64 1/4
Verifying : perl-Git-1.7.1-8.el6.noarch 2/4
Verifying : git-1.7.1-9.el6_9.x86_64 3/4
Verifying : perl-Git-1.7.1-9.el6_9.noarch 4/4

git.x86_64 0:1.7.1-9.el6_9 perl-Git.noarch 0:1.7.1-9.el6_9

git.x86_64 0:1.7.1-8.el6 perl-Git.noarch 0:1.7.1-8.el6

After rollback, use the following command to re-check the downgraded package version.

Rollback Updates using YUM downgrade command
Alternatively we can rollback an updates using YUM downgrade command.

yum downgrade git-1.7.1-8.el6 perl-Git-1.7.1-8.el6

Loaded plugins: search-disabled-repos, security, ulninfo
Setting up Downgrade Process
Resolving Dependencies
–> Running transaction check
—> Package git.x86_64 0:1.7.1-8.el6 will be a downgrade
—> Package git.x86_64 0:1.7.1-9.el6_9 will be erased
—> Package perl-Git.noarch 0:1.7.1-8.el6 will be a downgrade
—> Package perl-Git.noarch 0:1.7.1-9.el6_9 will be erased
–> Finished Dependency Resolution

Dependencies Resolved


Package Arch Version Repository Size

git x86_64 1.7.1-8.el6 base 4.6 M
perl-Git noarch 1.7.1-8.el6 base 29 k

Transaction Summary

Downgrade 2 Package(s)

Total download size: 4.6 M
Is this ok [y/N]: y
Downloading Packages:
(1/2): git-1.7.1-8.el6.x86_64.rpm | 4.6 MB 00:00

(2/2): perl-Git-1.7.1-8.el6.noarch.rpm | 28 kB 00:00

Total 3.7 MB/s | 4.6 MB 00:01
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : perl-Git-1.7.1-8.el6.noarch 1/4
Installing : git-1.7.1-8.el6.x86_64 2/4
Cleanup : perl-Git-1.7.1-9.el6_9.noarch 3/4
Cleanup : git-1.7.1-9.el6_9.x86_64 4/4
Verifying : git-1.7.1-8.el6.x86_64 1/4
Verifying : perl-Git-1.7.1-8.el6.noarch 2/4
Verifying : git-1.7.1-9.el6_9.x86_64 3/4
Verifying : perl-Git-1.7.1-9.el6_9.noarch 4/4

git.x86_64 0:1.7.1-9.el6_9 perl-Git.noarch 0:1.7.1-9.el6_9

git.x86_64 0:1.7.1-8.el6 perl-Git.noarch 0:1.7.1-8.el6

Note : You have to downgrade a dependence packages too, otherwise this will remove the current version of dependency packages instead of downgrade because the downgrade command cannot satisfy the dependency.

For Fedora Users
Use the same above commands and change the package manager command to DNF instead of YUM.

dnf list git

dnf history

dnf history info

dnf history undo

dnf list git

dnf downgrade git-1.7.1-8.el6 perl-Git-1.7.1-8.el6

dnf listgit

dnf history

dnf history info

dnf history undo

dnf listgit

dnf downgrade git-1.7.1-8.el6 perl-Git-1.7.1-8.el6

How to Backup and Restore RabbitMQ Data & Configurations

In this post, I’ll like us to look at how to perform a backup for RabbitMQ configurations and data. This will also include information on restoring a RabbitMQ backup into a new deployment.

Get Cluster Status

$ rabbitmqctl cluster_status
Cluster status of node rabbit@computingforgeeks-centos7 …
How to Backup RabbitMQ Configurations
Please note this backup doesn’t include Messages since they are stored in a separate message store. It will only backup RabbitMQ users, vhosts, queues, exchanges, and bindings. The backup file is a JSON representation of RabbitMQ metadata. We will do a backup using rabbitmqadmincommand line tool.

The management plugin ships with a command line tool rabbitmqadmin. You need to enable the management plugin:

rabbitmq-plugins enable rabbitmq_management
This plugin is used to perform some of the same actions as the Web-based UI, and which may be more convenient for automation tasks.

Download rabbitmqadmin
Once you enable the management plugin, download rabbitmqadmin Python command line tool that interacts with the HTTP API. It can be downloaded from any RabbitMQ node that has the management plugin enabled at

Once downloaded, make the file executable and move it to /usr/local/bin directory:

chmod +x rabbitmqadmin
sudo mv rabbitmqadmin /usr/local/bin
To backup RabbitMQ configurations, use the command:

rabbitmqadmin export

$ rabbitmqadmin export rabbitmq-backup-config.json
Exported definitions for localhost to “rabbitmq-backup-config.json”
The export will be written to filerabbitmq-backup-config.json.

How to Restore RabbitMQ Configurations backup
If you ever want to restore your RabbitMQ configurations from a backup, use the command:

rabbitmqadmin import

$ rabbitmqadmin import rabbitmq-backup.json
Imported definitions for localhost from “rabbitmq-backup.json”
How to Backup RabbitMQ Data
RabbitMQ Definitions and Messages are stored in an internal database located in the node’s data directory. To get the directory path, run the following command against a running RabbitMQ node:

rabbitmqctl eval ‘rabbit_mnesia:dir().’
Sample output:

This directory contains many files:

ls /var/lib/rabbitmq/mnesia/rabbit@computingforgeeks-centos7

cluster_nodes.config nodes_running_at_shutdown rabbit_durable_route.DCD rabbit_user.DCD schema.DAT
DECISION_TAB.LOG rabbit_durable_exchange.DCD rabbit_runtime_parameters.DCD rabbit_user_permission.DCD schema_version
LATEST.LOG rabbit_durable_exchange.DCL rabbit_serial rabbit_vhost.DCD
msg_stores rabbit_durable_queue.DCD rabbit_topic_permission.DCD rabbit_vhost.DCL
In RabbitMQ versions starting with 3.7.0 all messages data is combined in the msg_stores/vhosts directory and stored in a subdirectory per vhost. Each vhost directory is named with a hash and contains a .vhost file with the vhost name, so a specific vhost’s message set can be backed up separately.

To do RabbitMQ definitions and messages data backup, copy or archive this directory and its contents. But first, you need to stop RabbitMQ service

sudo systemctl stop rabbitmq-server.service
The example below will create an archive:

tar cvf rabbitmq-backup.tgz /var/lib/rabbitmq/mnesia/rabbit@computingforgeeks-centos7
How to Restore RabbitMQ Data
To restore from Backup, extract the files from backup to the data directory.

Internal node database stores node’s name in certain records. Should node name change, the database must first be updated to reflect the change using the following rabbitmqctl command:

rabbitmqctl rename_cluster_node
When a new node starts with a backed up directory and a matching node name, it should perform the upgrade steps as needed and proceed to boot.

Installing RabbitMQ on CentOS 7

I’ll take you through the installation of RabbitMQ on CentOS 7 / Fedora 29 / Fedora 28.

RabbitMQ is an open source message broker software that implements the Advanced Message Queuing Protocol (AMQP).

It receives messages from publishers (applications that publish them) and routes them to consumers (applications that process them).

Follow the steps below to install RabbitMQ on Fedora 29 / Fedora 28.

Step 1: Install Erlang
Before installing RabbitMQ, you must install a supported version of Erlang/OTP. The version of Erlang package available on EPEL repository should be sufficient.

sudo dnf -y install erlang
Confirm installation by running the erlcommand:

$ erl
Erlang/OTP 20 [erts-] [source] [64-bit] [smp:1:1] [ds:1:1:10] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V9.3.3.3 (abort with ^G)
Step 2: Add PackageCloud Yum Repository
A Yum repository with RabbitMQ packages is available from PackageCloud.

Create a new Repository file for RabbitMQ.

sudo vim /etc/yum.repos.d/rabbitmq_rabbitmq-server.repo




Step 3: Install RabbitMQ on Fedora 29 / Fedora 28
The last step is the actual installation of RabbitMQ:

sudo dnf makecache -y –disablerepo=’*’ –enablerepo=’rabbitmq_rabbitmq-server’
sudo dnf -y install rabbitmq-server
Confirm version of RabbitMQ installed:

$ rpm -qi rabbitmq-server
Name : rabbitmq-server
Version : 3.7.8
Release : 1.el7
Architecture: noarch
Install Date: Thu 15 Nov 2018 01:32:16 PM UTC
Group : Development/Libraries
Size : 10858832
License : MPLv1.1 and MIT and ASL 2.0 and BSD
Signature : RSA/SHA1, Thu 20 Sep 2018 03:32:57 PM UTC, Key ID 6b73a36e6026dfca
Source RPM : rabbitmq-server-3.7.8-1.el7.src.rpm
Build Date : Thu 20 Sep 2018 03:32:56 PM UTC
Build Host : 17dd9d9d-9199-4429-59e6-dc265f3581e9
Relocations : (not relocatable)
URL : http://www.rabbitmq.com/
Summary : The RabbitMQ server
Description :
RabbitMQ is an open source multi-protocol messaging broker.
Step 4: Start RabbitMQ Service
Now that you have RabbitMQ installed on your Fedora, start and enable the service to start on system boot.

sudo systemctl start rabbitmq-server
sudo systemctl enable rabbitmq-server

Step 5: Enable the RabbitMQ Management Dashboard (Optional)
You can optionally enable the RabbitMQ Management Web dashboard for easy management.

sudo rabbitmq-plugins enable rabbitmq_management
The Web service should be listening on TCP port 15672

ss -tunelp | grep 15672

tcp LISTEN 0 128* users:((“beam.smp”,pid=9525,fd=71)) uid:111 ino:39934 sk:9 <->
If you have an active Firewalld service, allow ports 5672 and 15672

sudo firewall-cmd –add-port={5672,15672}/tcp –permanent

By default, the guest user exists and can connect only from localhost. You can log in with this user locally with the password “guest”

To be able to login on the network, create an admin user like below:

rabbitmqctl add_user admin StrongPassword
rabbitmqctl set_user_tags admin administrator
Login with this admin username and the password assigned.

RabbitMQ User Management Commands
Delete User:

rabbitmqctl delete_user user
Change User Password:

rabbitmqctl change_password user strongpassword
Create new Virtualhost:

rabbitmqctl add_vhost /my_vhost
List available Virtualhosts:

rabbitmqctl list_vhosts
Delete a virtualhost:

rabbitmqctl delete_vhost /myvhost
Grant user permissions for vhost:

rabbitmqctl set_permissions -p /myvhost user “.” “.” “.*”
List vhost permissions:

rabbitmqctl list_permissions -p /myvhost
To list user permissions:

rabbitmqctl list_user_permissions user
Delete user permissions:

rabbitmqctl clear_permissions -p /myvhost user
The next article to read is:

sudo firewall-cmd –reload
Access it by opening the URL http://[server IP|Hostname]:15672

Ansibile yaml file

autocmd FileType yank setlocal ai ts=2 sw=2 et
vim set cursorcolumn color

iptables tips and tricks

Tip #1: Take a backup of your iptables configuration before you start working on it.

Back up your configuration with the command:

/sbin/iptables-save > /root/iptables-works

Tip #2: Even better, include a timestamp in the filename.

Add the timestamp with the command:

/sbin/iptables-save > /root/iptables-works-`date +%F`

You get a file with a name like:


If you do something that prevents your system from working, you can quickly restore it:

/sbin/iptables-restore < /root/iptables-works-2018-09-11
ln –s /root/iptables-works-`date +%F` /root/iptables-works-latest

Tip #4: Put specific rules at the top of the policy and generic rules at the bottom.

Avoid generic rules like this at the top of the policy rules:

iptables -A INPUT -p tcp --dport 22 -j DROP

The more criteria you specify in the rule, the less chance you will have of locking yourself out. Instead of the very generic rule above, use something like this:

iptables -A INPUT -p tcp --dport 22 –s –d -j DROP

This rule appends (-A) to the INPUT chain a rule that will DROP any packets originating from the CIDR block on TCP (-p tcp) port 22 (–dport 22) destined for IP address (-d

There are plenty of ways you can be more specific. For example, using -i eth0 will limit the processing to a single NIC in your server. This way, the filtering actions will not apply the rule to eth1.

Tip #5: Whitelist your IP address at the top of your policy rules.

This is a very effective method of not locking yourself out. Everybody else, not so much.

iptables -I INPUT -s <your IP> -j ACCEPT

You need to put this as the first rule for it to work properly. Remember, -I inserts it as the first rule; -A appends it to the end of the list.

Tip #6: Know and understand all the rules in your current policy.

Not making a mistake in the first place is half the battle. If you understand the inner workings behind your iptables policy, it will make your life easier. Draw a flowchart if you must. Also remember: What the policy does and what it is supposed to do can be two different things.

Set up a workstation firewall policy

Scenario: You want to set up a workstation with a restrictive firewall policy.

Tip #1: Set the default policy as DROP.

# Set a default policy of DROP

Tip #2: Allow users the minimum amount of services needed to get their work done.

The iptables rules need to allow the workstation to get an IP address, netmask, and other important information via DHCP (-p udp –dport 67:68 –sport 67:68). For remote management, the rules need to allow inbound SSH (–dport 22), outbound mail (–dport 25), DNS (–dport 53), outbound ping (-p icmp), Network Time Protocol (–dport 123 –sport 123), and outbound HTTP (–dport 80) and HTTPS (–dport 443).

# Set a default policy of DROP

# Accept any related or established connections

# Allow all traffic on the loopback interface
-A INPUT -i lo -j ACCEPT

# Allow outbound DHCP request
-A OUTPUT –o eth0 -p udp –dport 67:68 –sport 67:68 -j ACCEPT

# Allow inbound SSH
-A INPUT -i eth0 -p tcp -m tcp –dport 22 -m state –state NEW  -j ACCEPT

# Allow outbound email
-A OUTPUT -i eth0 -p tcp -m tcp –dport 25 -m state –state NEW  -j ACCEPT

# Outbound DNS lookups
-A OUTPUT -o eth0 -p udp -m udp –dport 53 -j ACCEPT

# Outbound PING requests
-A OUTPUT –o eth0 -p icmp -j ACCEPT

# Outbound Network Time Protocol (NTP) requests
-A OUTPUT –o eth0 -p udp –dport 123 –sport 123 -j ACCEPT

# Outbound HTTP
-A OUTPUT -o eth0 -p tcp -m tcp –dport 80 -m state –state NEW -j ACCEPT
-A OUTPUT -o eth0 -p tcp -m tcp –dport 443 -m state –state NEW -j ACCEPT


Restrict an IP address range

Scenario: The CEO of your company thinks the employees are spending too much time on Facebook and not getting any work done. The CEO tells the CIO to do something about the employees wasting time on Facebook. The CIO tells the CISO to do something about employees wasting time on Facebook. Eventually, you are told the employees are wasting too much time on Facebook, and you have to do something about it. You decide to block all access to Facebook. First, find out Facebook’s IP address by using the host and whois commands.

host -t a www.facebook.com
www.facebook.com is an alias for star.c10r.facebook.com.
star.c10r.facebook.com has address
whois | grep inetnum
inetnum: –

Then convert that range to CIDR notation by using the CIDR to IPv4 Conversion page. You get To prevent outgoing access to www.facebook.com, enter:

iptables -A OUTPUT -p tcp -i eth0 –o eth1 –d -j DROP

Regulate by time

Scenario: The backlash from the company’s employees over denying access to Facebook access causes the CEO to relent a little (that and his administrative assistant’s reminding him that she keeps HIS Facebook page up-to-date). The CEO decides to allow access to Facebook.com only at lunchtime (12PM to 1PM). Assuming the default policy is DROP, use iptables’ time features to open up access.

iptables –A OUTPUT -p tcp -m multiport –dport http,https -i eth0 -o eth1 -m time –timestart 12:00 –timestart 12:00 –timestop 13:00 –d  -j ACCEPT

This command sets the policy to allow (-j ACCEPT) http and https (-m multiport –dport http,https) between noon (–timestart 12:00) and 13PM (–timestop 13:00) to Facebook.com (–d

Regulate by time—Take 2

Scenario: During planned downtime for system maintenance, you need to deny all TCP and UDP traffic between the hours of 2AM and 3AM so maintenance tasks won’t be disrupted by incoming traffic. This will take two iptables rules:

iptables -A INPUT -p tcp -m time –timestart 02:00 –timestop 03:00 -j DROP
iptables -A INPUT -p udp -m time –timestart 02:00 –timestop 03:00 -j DROP

With these rules, TCP and UDP traffic (-p tcp and -p udp ) are denied (-j DROP) between the hours of 2AM (–timestart 02:00) and 3AM (–timestop 03:00) on input (-A INPUT).

Limit connections with iptables

Scenario: Your internet-connected web servers are under attack by bad actors from around the world attempting to DoS (Denial of Service) them. To mitigate these attacks, you restrict the number of connections a single IP address can have to your web server:

iptables –A INPUT –p tcp –syn -m multiport -–dport http,https –m connlimit -–connlimit-above 20 –j REJECT -–reject-with-tcp-reset

Let’s look at what this rule does. If a host makes more than 20 (-–connlimit-above 20) new connections (–p tcp –syn) in a minute to the web servers (-–dport http,https), reject the new connection (–j REJECT) and tell the connecting host you are rejecting the connection (-–reject-with-tcp-reset).

Monitor iptables rules

Scenario: Since iptables operates on a “first match wins” basis as packets traverse the rules in a chain, frequently matched rules should be near the top of the policy and less frequently matched rules should be near the bottom. How do you know which rules are traversed the most or the least so they can be ordered nearer the top or the bottom?

Tip #1: See how many times each rule has been hit.

Use this command:

iptables -L -v -n –line-numbers

The command will list all the rules in the chain (-L). Since no chain was specified, all the chains will be listed with verbose output (-v) showing packet and byte counters in numeric format (-n) with line numbers at the beginning of each rule corresponding to that rule’s position in the chain.

Using the packet and bytes counts, you can order the most frequently traversed rules to the top and the least frequently traversed rules towards the bottom.

Tip #2: Remove unnecessary rules.

Which rules aren’t getting any matches at all? These would be good candidates for removal from the policy. You can find that out with this command:

iptables -nvL | grep -v "0     0"

Note: that’s not a tab between the zeros; there are five spaces between the zeros.

Tip #3: Monitor what’s going on.

You would like to monitor what’s going on with iptables in real time, like with top. Use this command to monitor the activity of iptables activity dynamically and show only the rules that are actively being traversed:

watch --interval=5 'iptables -nvL | grep -v "0     0"'

watch runs ‘iptables -nvL | grep -v “0     0″‘ every five seconds and displays the first screen of its output. This allows you to watch the packet and byte counts change over time.

Report on iptables

Scenario: Your manager thinks this iptables firewall stuff is just great, but a daily activity report would be even better. Sometimes it’s more important to write a report than to do the work.

Use the packet filter/firewall/IDS log analyzer FWLogwatch to create reports based on the iptables firewall logs. FWLogwatch supports many log formats and offers many analysis options. It generates daily and monthly summaries of the log files, allowing the security administrator to free up substantial time, maintain better control over network security, and reduce unnoticed attacks.

SSL and TLS 1.3 on Nginx

I have heard that there is TLS1.3,

I have been tickle, I want to toss and try. In the past, there were not many browsers supported,
and there were not many people on the Internet who tried it. There are some large website sites that have already got TLS1.3,
and many bloggers have upgraded their blogs to TLS1.3, leaving valuable experience. I can’t help it anymore.
Let’s take a look at it today. Openssl 1.1.1 LTS has been released, update the official version of TLS1.3.

Software version
?Nginx: nginx-1.15.4
?OpenSSL: openssl-1.1.1(LTS)


Installation dependency

Sudo apt update
sudo apt install -y build-essential libpcre3 libpcre3-dev zlib1g-dev liblua5.1-dev libluajit-5.1-dev libgeoip-dev google-perftools libgoogle-perftools-dev

Download and unzip the required software

Wget https://nginx.org/download/nginx-1.15.4.tar.gz
tar zxf nginx-1.15.4.tar.gz
wget https://www.openssl.org/source/openssl-1.1.1. tar.gz
tar zxf OpenSSL-1.1.1.tar.gz

OpenSSL patching

Pushd openssl-1.1.1 #?TLS1.3 Draft 23, 26, 28, Final patch
curl https://raw.githubusercontent.com/hakasenyang/openssl-patch/master/openssl-equal-1.1.1_ciphers.patch | patch -p1
#?ign Strict-SNI log patch
curl https://raw.githubusercontent.com/hakasenyang/openssl-patch/master/openssl-ignore_log_strict-sni.patch | patch -p1

Nginx patch

Pushd nginx-1.15.4
#?SPDY, HTTP2 HPACK, Dynamic TLS Record, Fix Http2 Push Error, PRIORITIZE_CHACHA patch
curl https://raw.githubusercontent.com/kn007/patch/43f2d869b209756b442cfbfa861d653d993f16fe/nginx.patch | patch -p1
curl https ://raw.githubusercontent.com/kn007/patch/c59592bc1269ba666b3bb471243c5212b50fd608/nginx_auto_using_PRIORITIZE_CHACHA.patch | patch -p1
#? Strict-SNI patch
curl https://raw.githubusercontent.com/hakasenyang/openssl-patch/master/nginx_strict-sni .patch | patch -p1

Compile and install Nginx

If you have compiled and installed Nginx, you can enter nginx -V to view the previous configure configuration. Compile with the required parameters later.

Key parameters:
? Add –with-openssl=../openssl-1.1.1 to specify the OpenSSL path
?HTTP2 HPACK needs to add the –with-http_v2_hpack_enc parameter.
?SPDY needs to be added –with-http_spdy_module

Note that the –with-openssl parameter is changed to its own OpenSSL folder address.

My full configure command is as follows, please analogy.

Cd nginx-1.15.4

./configure \
–user=www \
–group=www \
–prefix=/usr/local/nginx \
–with-http_stub_status_module \
–with-threads \
–with-file-aio \
–with -pcre-jit \
–with-http_ssl_module \
–with-http_v2_module \
–with-http_gzip_static_module \
–with-http_sub_module \
–with-http_flv_module \
–with-http_mp4_module \
–with-http_gunzip_module \
–with -http_realip_module \
–with-http_addition_module \
–with-stream \
–with-stream_ssl_module \
–with-stream_ssl_preread_module \
–with-stream_realip_module \
–with-http_slice_module \
–with-http_geoip_module \
–with-google_perftools_module \
–with-openssl=../openssl-1.1.1 \
–with-http_v2_hpack_enc \

After configure is complete, enter the following statement to start compiling.


After the compilation is completed, if no error is reported, enter the following to install.

Make install

Configuring Nginx Web Hosting

Add the following to the appropriate location in your conf file to replace the original content. I removed TLS1 and TLS1.1 due to security upgrade considerations. In addition, the new cipher suite for TLS 1.3 can only be used in TLS 1.3, and the old cipher suite cannot be used for TLS 1.3. It seems that all virtual hosts must be configured to use TLS1.3.

Ssl_early_data on;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ecdh_curve X25519:P-256:P-384;
ssl_prefer_server_ciphers on;

Finally, use nginx -t to test the correctness of the nginx configuration.


Restart Nginx and you will find that your website is already connected to TLS1.3.

rminal window and follow these steps:

1. Generate the private key using the command sudo openssl genrsa -out ca.key 2048

2. Generate a CSR using the command sudo openssl req -new -key ca.key -out ca.csr

3. Use the command sudo openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt to generate a self-signed key

Now we need to copy the newly generated file to the correct location with the following command:

sudo cp ca.crt /etc/ssl/certs/
sudo cp ca.key /etc/ssl/private/
sudo cp ca.csr /etc/ssl/private/

Create an Nginx configuration

Remember, we want to enable SSL via TLS support. To do this, we must create a new Nginx configuration file with the following command:

Sudo nano /etc/nginx/conf.d/ssl.conf

In the file, paste the following:

Server {

Location / {
root /usr/share/nginx/html;
index index.html index.htm;

Listen 443 ssl;
server_name www.example.com;
ssl_certificate /etc/ssl/certs/ca.crt;
ssl_certificate_key /etc/ssl/private/ca.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers TLS- CHACHA20-POLY1305-SHA256: TLS-AES-256-GCM-SHA384: TLS-AES-128-GCM-SHA256: HIGH: !aNULL:!MD5;


Note: Be sure to change the root location to reflect your Nginx installation. However, if you follow the steps to build a Nginx that supports TLS, the above configuration should work.

Save and close the file. Test the new Nginx configuration file with the following command:

Sudo nginx -t

You should see the test passed.

Restart and test

Now we need to restart NGINX. Use the following command to do this:

Sudo systemctl restart nginx

Point your browser to https://SERVER_IP and you should see the NGINX welcome screen.
To ensure that your site is delivered with TLS 1.3 enabled, you can use the browser’s built-in tools.
For example, in Firefox, open the page and click the security button (the lock icon to the left of the address bar).
Click the right arrow associated with the page, then click More Info.
In the results window (Figure B), you should see the connection using TLS 1.3 encryption.

This is all about enabling SSL and TLS on the Nginx website.
Remember that you should use an SSL certificate from a reputable certification authority.
However, it is always a good idea to use a self-signed certificate for testing purposes.
Once you have confidence in this process, please purchase a certificate and deploy it to your Nginx site.

tomcat tuning

Sync sync disk

echo 3 > /proc/sys/vm/drop_caches # Clean up useless memory space

Tomcat8 final configuration
1.${tomcat}/bin/catalina.sh Join
JAVA_OPTS=”-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1G -Xmx1G -Xss256k -XX:NewSize=1G -XX:MaxNewSize=1G
-XX:PermSize=128m -XX:MaxPermSize=128m -XX:+DisableExplicitGC”

JAVA_OPTS=”$JAVA_OPTS -server -Xms3G -Xmx3G -Xss256k -XX:PermSize=128m -XX:MaxPermSize=128m -XX:+UseParallelOldGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/aaa/dump -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/usr/tomcat/dump/heap_trace.txt -XX:NewSize=1G -XX:MaxNewSize=1G”

Open commented out

<Executor name=”tomcatThreadPool” namePrefix=”catalina-exec-”
maxThreads=”300″ minSpareThreads=”50″/>

Add options not found in Connector

<Connector port=”80″ protocol=”org.apache.coyote.http11.Http11NioProtocol”

Detailed explanation of each parameter:

-Xms: Set the JVM initial memory size (default is 1/64 of physical memory)

-Xmx: Set the maximum memory that the JVM can use (default is 1/4 of physical memory, recommended: 80% of physical memory)

-Xmn: Set the minimum memory of the JVM (128-256m is enough, generally not set)

The default free heap memory is less than
At 40%, the JVM will increase the heap until the maximum limit of -Xmx; when the free heap memory is greater than 70%, the JVM will reduce the heap to the minimum limit of -Xms. So the server is generally set to -Xms,
-Xmx is equal to avoid resizing the heap after each GC.

In larger applications, the default memory is not enough and may cause the system to fail. A common problem is to report a Tomcat memory overflow error “java.lang.OutOfMemoryError:
Java heap space”, causing the client to display 500 errors.

-XX:PermSize : Perm memory size when starting the JVM

-XX:MaxPermSize : is the maximum available Perm memory size (default is 32M)

-XX:MaxNewSize, default is 16M

The full name of PermGen space is Permanent Generation
Space, refers to the permanent storage area of ??memory, this memory is mainly stored by the JVM Class and Meta information, Class will be placed in PermGen when it is Loader
In space, it is different from the Heap area that stores the instance (Instance), GC (Garbage
Collection) will not be in the main program runtime against PermGen
Space is cleaned up, so if your application has a very CLASS, it is likely to appear “java.lang.OutOfMemoryError:
PermGen space” error.

For WEB projects, when jvm loads a class, the objects in the permanent domain increase sharply, so that jvm constantly adjusts the size of the permanent domain. To avoid adjustments, you can use more parameter configuration. If your WEB
APP uses a large number of third-party jars, the size of which exceeds the default size of jvm, then this error message will be generated.

Other parameters:

-XX:NewSize: The default is 2M. This value is set to a large adjustable new object area, reducing Full.
GC times

-XX:NewRatio : Change the proportion of new and old space, which means that the size of the new space is 1/8 of the old space (default is 8)

-XX:SurvivorRatio: Change the size ratio of the Eden object space and the remaining space, meaning that the Eden object is empty.

The size between the two is greater than the survivor space by 2 times survivorRatio (default is 10)

-XX:userParNewGC can be used to set parallel collection [multiple CPU]

-XX:ParallelGCThreads can be used to increase parallelism [multiple CPU]

-XXUseParallelGC can be set to use parallel clear collector [multi-CPU]

The maximum number of request processing threads to be created by this Connector, which therefore determines the maximum number of simultaneous requests that can be handled.If not specified, this attribute is set to 200. If an executor is associated with this connector, this attribute is ignored as the connector will execute tasks using the executor rather than an internal thread pool.
The minimum number of threads always kept running. If not specified, the default of 10 is used.
The number of milliseconds this Connector will wait, after accepting a connection, for the request URI line to be presented. Use a value of -1 to indicate no (i.e. infinite) timeout. The default value is 60000 (i.e. 60 seconds) but note that the standard server.xml that ships with Tomcat sets this to 20000 (i.e. 20 seconds). Unless disableUploadTimeout is set to false, this timeout will also be used when reading the request body (if any).
If set to true, the TCP_NO_DELAY option will be set on the server socket, which improves performance under most circumstances. This is set to true by default.
The size (in bytes) of the buffer to be provided for socket output buffering. -1 can be specified to disable the use of a buffer. By default, a buffers of 9000 bytes will be used.
Overrides the Server header for the http response. If set, the value for this attribute overrides the Tomcat default and any Server header set by a web application. If not set, any value specified by the application is used. If the application does not specify a value then Apache-Coyote/1.1 is used. Unless you are paranoid, you won’t need this feature.
The maximum size of the request and response HTTP header, specified in bytes. If not specified, this attribute is set to 8192 (8 KB).
The maximum number of HTTP requests which can be pipelined until the connection is closed by the server. Setting this attribute to 1 will disable HTTP/1.0 keep-alive, as well as HTTP/1.1 keep-alive and pipelining. Setting this to -1 will allow an unlimited amount of pipelined or keep-alive HTTP requests. If not specified, this attribute is set to 100.
For BIO the default is the value of maxThreads unless an Executor is used in which case the default will be the value of maxThreads from the executor. For NIO the default is 10000. For APR/native, the default is 8192.
The number of milliseconds this Connector will wait for another HTTP request before closing the connection. The default value is to use the value that has been set for the connectionTimeout attribute. Use a value of -1 to indicate no (i.e. infinite) timeout.

Database Pool Configuration

<Resource name=”jdbc/productdb” auth=”Container” type=”javax.sql.DataSource”
maxTotal=”10″ maxIdle=”30″ maxWaitMillis=”10000″ logAbandoned=”true”
username=”root” password=”admin” driverClassName=”com.mysql.jdbc.Driver”

JVM Settings
We have set the minimum and maximum heap size to 1GB respectively as below:

export CATALINA_OPTS=”-Xms1024m -Xmx1024m”

-Xms – Specifies the initial heap memory
-Xmx – Specifies the maximum heap memory

AJP Connector configuration
The AJP connector configuration below is configured so that there are two threads allocated to accept new connections.
This should be configured to the number of processors on the machine however two should be suffice here.
We have also allocated 400 threads to process requests, the default value is 200.
The “acceptCount” is set to 100 which denotes the maximum queue length to be used for incoming connections.
The default value is 10. Lastly we have set the minimum threads to 20 so that there are always 20 threads running in the pool to service requests:

<Connector port=”8009″ protocol=”AJP/1.3″ redirectPort=”8443″ acceptorThreadCount=”2″ maxThreads=”400″ acceptCount=”200″ minSpareThreads=”20″/>

Database Pool Configuration
We have modified the maximum number of pooled connections to 200 so that there are ample connections in the pool to service requests.

<Resource name=”jdbc/productdb” auth=”Container” type=”javax.sql.DataSource”
maxTotal=”200″ maxIdle=”30″ maxWaitMillis=”10000″ logAbandoned=”true”
username=”xxxx” password=”xxxx” driverClassName=”com.mysql.jdbc.Driver”

JVM Settings
Since we have increased the maximum number of pooled connections and AJP connector thread thresholds above,
we should increase the heap size appropriately. We have set the minimum and maximum heap size to 2GB respectively as below:

export CATALINA_OPTS=”-Xms2048m -Xmx2048m”

JVM Heap Monitoring and Tuning

Specifying appropriate JVM heap parameters to service your deployed applications on Tomcat is paramount to application performance.
There are a number of different ways which we can monitor JVM heap usage including using JDK hotspot tools such as jstat, JConsole etc. –
however to gather detailed data on when and how garbage collection is being performed, it is useful to turn on GC logging on the Tomcat instance.
We can turn on GC logging by modifying the catalina start up script with the following command:

JAVA_OPTS=”$JAVA_OPTS -verbose:gc -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps”

We can set the minimum and maximum heap size,
the size of the young generation and the maximum amount of memory to be allocated to the permanent generation used to store application class metadata by specifying the setting the CATALINA_OPTS parameter by executing this command:

export CATALINA_OPTS=”-Xms1024m -Xmx2048m -XX:MaxNewSize=512m -XX:MaxPermSize=256m”

This configuration is optimized for REST/HTTP API call. And it doesn’t use any reverse proxy like Apache, NginX etc. We will reside simple L4 switch infront of tomcat groups.

In addition we will not use Tomcat Clustering, Session etc. So the clustering configuration is omitted.

Listener Setting
<Listener className=”org.apache.catalina.security.SecurityListener” checkedOsUsers=”root” />

checkedOsUser setting means Unix system user “root” cannot start Tomcat. If user starts tomcat as a root user it makes log file as a root user permission. In that case tomcat user cannot delete the log file.

<Listener className=”org.apache.catalina.core.JreMemoryLeakPreventionListener” />

This makes detect memory leak.

Connector Setting

It makes tomcat use BIO. Tomcat has options for IO (BIO,NIO,APR). APR is fastest IO setting. It uses Apache web server IO module, so it is fastest. But it uses C code (JNI call), it can have a risk to kill tomcat instance. (with core dump). APR is more faster about 10% than BIO. But BIO is more stable. Use BIO. (Default is BIO)


It specifies server request queue length. If message is queued in the request queue, it means server cannot handle incoming message (it is overloaded). It will wait for idle thead and the request message will be pending. This setting reduce total size of request queue to 10. If the queue has been overflowed, client will get a error. It can protect server from high overload and let system manager to know the server has been overloaded.


In Java Servlet Code, user can look up request message origin (IP or URL).

For example user in yahoo.com send request to server, and Tomcat try to resolve incoming request IP address.
“enableLooksups” option enables return DNS name not a IP address. During this processing Tomcat look up DNS.
It brings performance degradation. This option removes DNS look up stage and increase performance.


We are using REST protocol not a normal web contents like HTML,Image etc.
This options allows to compress HTTP message. It consumes computing power but it can reduce network payload.
In our environment compression is not required. It is better to save computing power. And in some particular Telco network, compression is not supported.


It is HTTP Connection time out (client to server). It is milliseconds. (10,000 = 10 sec).

If server cannot make a connection from client til 10 sec. It will throw HTTP time out error.
In normal situation, our API response time is under 5 sec. So 10 sec means, server has been overloaded.
The reason why I increased the time up to 10 sec is, depends on network condition, connection time will be deferred.


The maximum number of connection, tomcat can handle. It means tomcat can handle maximum 8192 socket connection in a time. This value is restricted by Unix system parameter “ulimit –f” (You can check up in unix console)


As I mentioned above, this configuration is optimized to REST API request not a common web system. It means client will send REST API call only. It sends the request and get a response. Client will not send request in a short time. It means we cannot reuse the connection from the client. So this setting turn of HTTP Keep Alive. (After response the request from client, tomcat disconnect the connection immediately)


This defines total number of thread in Tomcat. It represents max number of active user at that time. Usually 50~500 is good for performance. And 100~200 is best (it is different depends on use case scenario).

Please test with 100 and 200 values and find value for performance. This parameter also get a impact from DB connection pool setting, even if we have a lot of thread , and the total number of db connection is not enough, the thread will wait to acquire the connection.


This allows us to use TCP_NO_DELAY in tcp/ip layer. It makes send small packet without delay. In TCP, to reduce small package congestion, it gathers small packet to tcp buffer until it has been filled and send the packet. TCP_NO_DELAY option makes send small packet immediately even though TCP buffer is not full.

JVM Tuning
Java Virtual Machine tuning is also very important factor to run Tomcat

The focus of JVM tuning is reducing Full GC time.


This option makes JVM to optimize server application. It tunes HotSpot compiler etc internally. This option is very important and mandatory in server side application

-Xmx1024m –Xms1024m -XX:MaxNewSize=384m -XX:MaxPermSize=128m

This memory tuning options, our infrastructure is using c1.mediuem amazon instance, so the available memory is about 1.7 gb total. Heap size is 1G and let them to have fixed size. It defines max 1Gb, min 1Gb heap size. The NewSize is 384mb (1/3 size of total heap size). 1/3 New Size is best performance usually. Perm size is defines area of memory to load class. 64mb is enough. But we will use 128m first time and tune based on gc log analysis later.

Total physical memory consumption is 1G heap + 128mb perm = 1.128 GB and JVM internally uses memory to run JVM itself. It consumes about 350~500mb. So total estimated required memory is about 1.128GB+500m = 1.5 GB.

As I mentioned, c1.mediuem size has only 1.7GB physical memory. If consumed memory exceeds actual physical memory, it makes disk swapping. If JVM memory is swapped out to disk, the performance is significantly degraded. Please take care swapping is not occurred.

-XX:-HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./java_pid<pid>.hprof

These options are for trouble shooting “OOM (Java Out Of Memory Error”. If out of memory error has been occurred. The memory layout will be dumped to disk. The location of dumpfile is specified by “-XX:HeapDumpPath” option

-XX:ParallelGCThreads=2 -XX:-UseConcMarkSweepGC

These options specify GC strategy. It uses ParallelGC for Minor collection and 2 threads will be used for the Minor GC. And for Old area, concurrent gc will be used. It will reduce Full gc time

-XX:-PrintGC -XX:-PrintGCDetails -XX:-PrintGCTimeStamps -XX:-TraceClassUnloading -XX:-TraceClassLoading

These option specifies GC logging. It logs the GC log detail to stderr (console output). It shows usage trend os Java Heap memory, time stamp etc. (it contains old,new & perm area usage).

Especially, ClassLoading & UnLoading option show what class is loaded and unloaded to memory. It helps us to trace Perm Out of memory error.