Remove or hide client sender IP from Postfix on SMTP relay

Sometimes we need to hide our IP address for security, if we use Cloudflare we need to create separate email server so our IP site origin will keep hidden.

The following is how to to remove client sender IP (X-Originating-IP) from Postfix generated email header and the only available data is IP from our email server.

Open /etc/postfix/ and find:

cleanup   unix  n       -       n       -       0       cleanup

Add below those line and become:

cleanup   unix  n       -       n       -       0       cleanup
  -o header_checks=pcre:/etc/postfix/header_checks

Edit /etc/postfix/header_checks and add below codes:

/^Received:/ IGNORE

Now restart postfix. Let say on CentOS:

service postfix restart

Check Disk Health Status When Using Hardware RAID

I have several boxes using RAID controller from LSI brands. And of course, sometimes we need to know important information about our disks, let say disk health status.

When using Software RAID then the command is very simple, eg:

smartctl -a /dev/sda

However, when using a hardware RAID, the command is slightly different:

# Physical drive information
MegaCli -PDList -aALL

# Outputting device ID
MegaCli -PDList -aALL | grep "Device Id"

# Smartctl test
smartctl -a -d sat+megaraid,#DeviceID /dev/sd[a-z]

Note: the RAID controller is MegaRAID LSI.

Setting Up NAT VPS on CentOS 6 using IP Tables and HAProxy

When ordering dedicated server sometimes we only got 1 IPv4, but that’s enough, we can using NAT for container with IP Tables and HAProxy to creating many OpenVZ VPS inside our dedicated server.

Install OpenVZ

yum update -y

yum install -y wget

cd /etc/yum.repos.d


rpm --import

yum install -y vzkernel.x86_64

yum install -y vzctl vzquota

yum install -y ploop

sed -i 's/kernel.sysrq = 0/kernel.sysrq = 1/g' /etc/sysctl.conf

sed -i 's/net.ipv4.ip_forward = 0/net.ipv4.ip_forward = 1/g' /etc/sysctl.conf

echo 'net.ipv4.conf.default.proxy_arp = 0' >> /etc/sysctl.conf

echo 'net.ipv4.conf.all.rp_filter = 1' >> /etc/sysctl.conf

echo 'net.ipv4.conf.default.send_redirects = 1' >> /etc/sysctl.conf

echo 'net.ipv4.conf.all.send_redirects = 0' >> /etc/sysctl.conf

echo 'net.ipv4.icmp_echo_ignore_broadcasts=1' >> /etc/sysctl.conf

echo 'net.ipv4.conf.default.forwarding=1' >> /etc/sysctl.conf

sysctl -p

sed -i 's/NEIGHBOUR_DEVS=detect/NEIGHBOUR_DEVS=all/g' /etc/vz/vz.conf

sed -i 's/options nf_conntrack ip_conntrack_disable_ve0=1/options nf_conntrack ip_conntrack_disable_ve0=0/g' /etc/modprobe.d/openvz.conf

sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux

yum install -y ntp

ntpdate -u

chkconfig ntpd on


Install OpenVZ Web Panel

Now we can install the OpenVZ Web Panel:

wget -O - | sh

Open http://PublicIP:3000 in your browser (Login admin/admin, make sure to change your default password).

For private IP, I pick this IP range, and let say our public IP is, and our virtual server IP is set to using OpenVZ Web Panel.

Provide access for container to Internet

Use below rule so our container can access the internet:

iptables -t nat -A POSTROUTING -s -o eth0 -j SNAT --to

SSH for virtual server (port forwarding)

User can access their VPS trough SSH by using our public IP and custom port, I pick port 2122.

iptables -t nat -A PREROUTING -p tcp -d --dport 2122 -j DNAT --to-destination

Save the iptables:

service iptables save

Restart iptables:

service iptables restart

HAProxy (web access)

We can use HAProxy to bind any http request to our private IPs (DNAT). Install HAProxy first:

rpm -ivh

yum install -y haproxy

Now configure the /etc/haproxy/haproxy.cfg, example:

frontend httpd
    bind *:80
    acl example_www hdr_end(host) -i
    use_backend example_http if example_www

backend example_http
    mode http
    server localhost-stash-http

Start HAProxy and set to start automatically on reboot:

service haproxy start

chkconfig haproxy on


If you prefer using nginx instead of haproxy than install nginx first:

rpm -ivh

yum install nginx

Than creating your nginx configurations, example:

server {
  listen 80;
    location / {
      access_log off;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header Host $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_buffering    off;
      proxy_buffer_size  128k;
      proxy_buffers 100  128k;


When you start OpenVZ service and you got Running kernel is not an OpenVZ kernel message, you’ll just need to modify /boot/grub/grub.conf manually, example:


    title OpenVZ (2.6.32-042stab090.5)
        root (hd0,0)
        kernel /boot/vmlinuz-2.6.32-042stab090.5 root=/dev/sda1  ro
        initrd /boot/initramfs-2.6.32-042stab090.5.img

Important! pick kernel that has stab filename, if mistaken than our dedibox will not booting, after checking the grub.conf file properly than reboot it.

Updating Discourse on CentOS

I have one forum using Discourse, as a test for this new platform, for OS I use CentOS. Discourse official documentation to updating the site is using Ubuntu so there are a few changes need to be done for CentOS.

My SSH login name is Discourse and the installation folder is inside the Discourse folder, example url


Here's how to update Discourse to the latest version:

# Run these commands as the discourse user
bluepill stop
bluepill quit

# Back up your install

pg_dump --no-owner --clean discourse_prod | gzip -c > ~/discourse-db-$DATESTAMP.sql.gz

tar cfz ~/discourse-dir-$DATESTAMP.tar.gz -C /home/discourse discourse

# Get the latest Discourse code
cd discourse
git checkout master
git pull
git fetch --tags

# To run on the latest numbered release instead of bleeding-edge:
# git checkout latest-release

# Merge the sample configuration just in case if there is an update. Run these commands as the discourse user

diff -u config/discourse_defaults.conf config/discourse.conf

diff -u config/discourse.pill.sample config/discourse.pill

diff -u config/nginx.sample.conf /etc/nginx/conf.d/discourse.conf

# Begin upgrade
bundle install --without test --deployment

RUBY_GC_MALLOC_LIMIT=90000000 RAILS_ENV=production bundle exec rake db:migrate

RUBY_GC_MALLOC_LIMIT=90000000 RAILS_ENV=production bundle exec rake assets:precompile

RUBY_GC_MALLOC_LIMIT=90000000 RAILS_ROOT=/home/discourse/discourse RAILS_ENV=production NUM_WEBS=2 bluepill --no-privileged -c ~/.bluepill load /home/discourse/discourse/config/discourse.pill

# Restart bluepill
crontab -l