Wednesday, June 3, 2020

Centos 8: [How-to] install Mysql 5.6/5.7/8.0 PHP 5.6/7.4 and Virtualmin

Here is the gist I use to install Virtualmin / Mysql / PHP on CentOS 8 :

# Fixing perl locale warning
echo "LANGUAGE=en_US.utf8
LC_ALL=en_US.utf-8
LANG=en_US.utf8
LC_TYPE=en_US.utf8" > /etc/environment

# Logout SSH and Login again to apply env

# Installing Mysql/Remi repo and required packages
yum install epel-release -y
yum install https://rpms.remirepo.net/enterprise/remi-release-8.rpm htop wget perl perl-DBD-MySQL screen net-tools yum-utils unzip glibc-langpack-en lsof vim-enhanced git nload iotop bind-utils tar zip telnet -y 

# Disabling default mysql mariadb php modules on centos 8
dnf module disable mysql mariadb php -y
echo "exclude=mariadb*" >> /etc/yum.conf

# Remi provides modular packages for PHP 7.2+
yum-config-manager --enable remi
dnf module enable php:remi-7.4 -y
yum update -y

## Instructions for Mysql 8.0
yum install https://dev.mysql.com/get/mysql80-community-release-el8-1.noarch.rpm -y
yum install mysql-community-server
sed -i /etc/my.cnf -e "s,# default-authentication-plugin=mysql_native_password,default-authentication-plugin=mysql_native_password,g"
service mysqld start
echo "validate_password.policy=LOW" >> /etc/my.cnf
echo "max_allowed_packet = 100M" >> /etc/my.cnf

service mysqld restart

## Instructions for Mysql 5.7/5.6 from mysql's el7 repo
yum install https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm -y
yum-config-manager --disable mysql80-community
yum-config-manager --enable mysql57-community
yum install mysql-community-server
mysql -e "uninstall plugin validate_password;"
echo "max_allowed_packet = 100M" >> /etc/my.cnf
###

# Installing Virtualmin
echo "set nocompatible" > /root/.vimrc
wget http://software.virtualmin.com/gpl/scripts/install.sh
sh install.sh -m

# Configuring Virtualmin

sed -i /etc/webmin/virtual-server/*config -e "s/ Options=ExecCGI,Includes,IncludesNOEXEC,Indexes,MultiViews,SymLinksIfOwnerMatch//g"
sed -i /etc/webmin/mysql/config -e "s,mariadb,mysqld,g"
sed -i /etc/webmin/virtual-server/*config -e "s,quotas=1,quotas=0,g"
sed -i /etc/webmin/virtual-server/*config -e "s,collect_restart=0,collect_restart=1,g"
virtualmin set-global-feature --enable-feature ssl --default-on ssl

virtualmin set-global-feature --disable-feature virtualmin-dav --default-off virtualmin-dav
service webmin restart

# php 5.6
yum install php56-php-bcmath php56-php-common php56-php-gd php56-php-intl php56-php-ioncube-loader php56-php-litespeed php56-php-mbstring php56-php-mcrypt php56-php-mysqlnd php56-php-opcache php56-php-pdo php56-php-pecl-jsonc php56-php-pecl-zip php56-php-soap php56-php-xml php56-runtime php56-php-fpm php56-php-cgi php-zip -y

# php 7.3
dnf module install php:remi-7.3
dnf install php73-php-bcmath php73-php-common php73-php-gd php73-php-intl php73-php-ioncube-loader php73-php-litespeed php73-php-mbstring php73-php-mcrypt php73-php-mysqlnd php73-php-opcache php73-php-pdo php73-php-pecl-jsonc php73-php-pecl-zip php73-php-soap php73-php-xml php73-runtime php73-php-fpm php73-php-cgi php-zip -y

dnf install php-bcmath php-common php-gd php-intl php-ioncube-loader php-litespeed php-mbstring php-mcrypt php-mysqlnd php-opcache php-pdo php-pecl-zip php-soap php-xml php-zip -y

# Limit DNS recursion in named
# add to /etc/named.conf
allow-recursion { localhost; };

# Disable UseDNS in sshd
# Update /etc/ssh/sshd_config
UseDNS No

# Mysql config
# add to /etc/my.cnf
symbolic-links=0
local-infile=0
sql_mode = "NO_ENGINE_SUBSTITUTION"
collation-server = utf8mb4_unicode_ci
init-connect='SET NAMES utf8mb4'
character-set-server = utf8mb4


# Apache config:
echo '<IfModule mod_expires.c>
# Enable expirations
ExpiresActive On
# Default directive
# ExpiresDefault "access plus 15 days"
# My favicon
ExpiresByType image/x-icon "access plus 15 days.
# Images
ExpiresByType image/gif "access plus 15 days"
ExpiresByType image/png "access plus 15 days"
ExpiresByType image/jpg "access plus 15 days"
ExpiresByType image/jpeg "access plus 15 days"
# CSS
ExpiresByType text/css "access 15 days.
# Javascript
ExpiresByType application/javascript "access plus 15 days"
</IfModule>' > /etc/httpd/conf.d/expires.conf


echo '<IfModule deflate_module>
<Location />
SetOutputFilter DEFLATE
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png|swf)$ no-gzip dont-vary
</Location>
</IfModule>' > /etc/httpd/conf.d/deflate.conf

echo '<IfModule event.c>
    ServerLimit           15
    MaxClients           960
    StartServers           2
    ThreadsPerChild       64
    ThreadLimit           64
    MinSpareThreads       32
    # must be >= (MinSpareThreads + ThreadsPerChild)
    MaxSpareThreads      112
    # at 200 r/s, 20000 r results in a process lifetime of 2 minutes
    MaxRequestsPerChild 20000
</IfModule>' > /etc/httpd/conf.d/mpm.conf

# update mpm in /etc/httpd/conf.modules.d/00-mpm.conf

# high performance mpm_event /etc/httpd/conf.d/mpm.conf:

<IfModule event.c>
    ServerLimit           64
    ThreadsPerChild   256
    ThreadLimit           256
    MaxRequestWorkers   4096
    StartServers           2
    MinSpareThreads       32
    # must be >= (MinSpareThreads + ThreadsPerChild)
    MaxSpareThreads      112
    # at 200 r/s, 20000 r results in a process lifetime of 2 minutes
    MaxRequestsPerChild 20000
</IfModule>


# move /tmp to ram: /etc/fstab
tmpfs /tmp tmpfs mode=1777,nosuid,nodev 0 0


# /etc/php.ini
#update:
upload_max_filesize
post_max_size
memory_limit
max_execution_time
max_input_time


# Install Node.js 14.x
curl -sL https://rpm.nodesource.com/setup_14.x | bash -
yum install -y nodejs

# Install pm2 
npm i -g pm2

# Here is a helloworld node.js app.js 
const http = require('http');
http.createServer(function(request, response) {
  response.writeHead(200, {'Content-Type': 'text/plain'});
  response.end("Hello, World!\n");
}).listen(process.env.PORT);
console.log('7001');

# create a virtual server and place the app.js file then run the following commands to activate it

sudo -u $user pm2 start app.js
sudo -u $user pm2 save
sudo -u $user pm2 startup

# then proxypass requests in apache to the app
ProxyPass / http://127.0.0.1:7001/ timeout=60
ProxyPassReverse / http://127.0.0.1:7001/

# Installing ffmpeg gz 
sudo yum-config-manager --add-repo=https://negativo17.org/repos/epel-multimedia.repo
yum install ffmpeg -y

Friday, May 29, 2020

Forward Traffic from Public IP to Wireguard client behind NAT and Preserve IP

Wiregurad allows us to create virtual network interfaces between nodes that are in separate networks. This feature can be used to expose a server behind NAT with a Public IP address.

The main advantage of the method described in this post is that it preserves clients IP address, so the home server sees the real IP address of clients and can process them (e.g. block them in a firewall).

There are several posts on the internet on this topic however they are not complete, for example the method described in this post does not preserve IP address of clients and shows the wireguard server's IP address in requests instead.

Wireguard allows the Server in NAT accessible via VPS Public IP

I had an asterisk server at home on raspberry pi, and wanted to make it accessible via internet however the internet solution that was used there did not provide a public IP address. It's possible to create a SSH tunnel and forward ports using a VPS in a datacenter however  it would not preserve clients IP address. I wanted to see the real address of clients so that fail2ban can block bruteforce attacks against the asterisk server.

Steps:

VPS Server:
1. Enable net.ipv4.ip_forward on the VPS

2. Wireguard config on the VPS server is simple and does not have anything special:

[Interface]
Address = 10.0.1.1
ListenPort = <Wireguard Listen Port>
PrivateKey = <Wireguard VPS Server Private Key>

# Home
[Peer]
PublicKey = <Wireguard on Home server Public Key>
AllowedIPs = 10.0.1.2/32

where 10.0.1.1 is the local IP address of wireguard on VPS server and 10.0.1.2 is the local IP address of wireguard on Home server behind NAT.

3. Now, to forward Traffic to the VPS server, you need to use the following rules in IP tables : 

# To allow Forwarding IPs in IPtables: 
iptables -A FORWARD -i wg0 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o wg0 -j ACCEPT

# This rule can be used if it is not needed tp preserve clients IP
# iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE

This rule is needed to provide internet to Home server when preserving clients IP
iptables -t nat -A POSTROUTING -s '10.0.1.0/24' -o eth0 -j MASQUERADE

# Forward TCP / UDP ports here to the server home
# TCP Public:8080 -> Home:443
iptables -t nat -A PREROUTING -p tcp -d VPS.Public.IP.Address --dport 8080 -j DNAT --to-destination 10.0.1.2:443
# TCP Public:8822 -> Home:22
iptables -t nat -A PREROUTING -p tcp -d VPS.Public.IP.Address --dport 8822 -j DNAT --to-destination 10.0.1.2:22
# UDP Public:5060 -> Home:5060
iptables -t nat -A PREROUTING -p udp -d VPS.Public.IP.Address --dport 5060 -j DNAT --to-destination 10.0.1.2:5060
# UDP Range Public:11000-11200 -> Home:11000-11200
iptables -t nat -A PREROUTING -p udp -d VPS.Public.IP.Address --dport 11000:11200 -j DNAT --to-destination 10.0.1.2:11000-11200

Home server in NAT: 
Wireguard config on the Home server is a bit more tricky. 

[Interface]
PrivateKey = <Wireguard on Home server Private Key>
Address = 10.0.1.2

[Peer]
PublicKey = <Wireguard VPS Server Public Key>

# This rule will not preserve clients IP 
# AllowedIPs = 10.0.1.1/24
# This rule will preserve clients IP:
# This is a Sample range, you need to use the script provided below to 
# exclude you VPS IP / Local NAT IP from 0.0.0.0/0 range, then use it here
AllowedIPs = 128.0.0.0/1, 64.0.0.0/2, 32.0.0.0/3, 16.0.0.0/4, 0.0.0.0/5, 12.0.0.0/6, 10.0.0.0/7, 9.0.0.0/8, 8.128.0.0/9, 8.64.0.0/10, 8.32.0.0/11, 8.16.0.0/12, 8.0.0.0/13, 8.12.0.0/14, 8.10.0.0/15, 8.9.0.0/16, 8.8.128.0/17, 8.8.64.0/18, 8.8.32.0/19, 8.8.16.0/20, 8.8.0.0/21, 8.8.12.0/22, 8.8.10.0/23, 8.8.9.0/24, 8.8.8.128/25, 8.8.8.64/26, 8.8.8.32/27, 8.8.8.16/28, 8.8.8.0/29, 8.8.8.12/30, 8.8.8.10/31, 8.8.8.9/32
Endpoint = <VPS PUBLIC IP>:<Wireguard Listen Port>
PersistentKeepalive = 25 

AllowedIPs is the tricky part here. 

One can use AllowedIPs = 10.0.1.1/24 here with iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE  rule in iptables of the VPS, this will let the home server to be accessible through the forwarded ports, however the home server will not see the real IP address of clients, and will  see all requests coming from 10.0.1.1, the IP address of wireguard VPS instead.

To let the home server accessible through the Public IP address of VPS and make it see the real IP address of clients, it is required to route packets that arrive to server home to come back through wireguard. So basically we need to add all IP ranges to AllowedIPs Except VPS IP address and other local network addresses that we dont want to go through wireguard.

It is not possible to use AllowedIPs = 0.0.0.0/0 directly, as wireguard will not be able to connect to our VPS IP address then. We also don't want our Local NAT IP range to go through Wireguard.  So we use the following Shell script to exclude our VPS IP/Local IP range from 0.0.0.0/0 range :

#!/bin/bash
echo "enter the broader range e.g. 176.0.0.0/4"
read r1
echo "enter the exclude ip e.g. 18.20.18.8/32"
read r2
pshell=`cat <<EOF
import ipaddress
n1 = ipaddress.ip_network('$r1')
n2 = ipaddress.ip_network('$r2')
l = list(n1.address_exclude(n2))
print(l)`

python3 -c "$pshell" | sed -e "s,IPv4Network(',,g" | sed -e "s,'),,g" | sed -e "s,\[,,g" | sed -e "s,\],,g"

It requires ipaddress python3 package to work.

Thursday, April 16, 2020

VoIP / SIP Settings on different versions of Android

Android phones come with a native VoIP client that works great. The settings are placed in different paths though, in this post I'll list the path to the setting on different versions of Android:

Android 4.2.2 (Jelly Bean) - (Huawei Y330):
Dialer App -> Settings -> Internet Call

Android 5.0 (Lollipop) -  Asus Fonepad 7 FE171CG:
Settings -> Call Settings -> Phone account settings

Android 5.1.1 ((Lollipop)  - Huawei Redmi 3:
Phone App -> Settings -> Advanced Settings -> SIP Settings

Android 9 (Pie) - Mi A3 / A1:
Phone App -> Settings -> Calling Accounts

Wednesday, April 15, 2020

How to configure VoIP on GreenPacket DT-350

آموزش راه اندازی تلفن اینترنتی VoIP بر روی مودم TD-LTE DT-350 ایرانسل

Irancell TD-LTE TD-350 modem offers a hardware VoIP client and one can connect a phone to the RJ45 port on the modem to use this feature. However, VoIP settings are disabled by default and it is not possible to enable it using the admin user since this user is an Enduser and not a Superuser.

 


Thanks to this post, it is possible to find the superuser defined for Greenpacket modems. Irancell has set the username for superuser on its modems to administrator and the password is also administrator: 

User: administrator
Pass: administrator

This user has privileges to manage many more settings including VoIP settings :



And Voila! It works pretty well!




Sunday, March 29, 2020

Lantronix KVM Java error FIX: Use Latronix native client instead

Latronix KVM provides HTML5 console however its not possible to mount images there so you would need to set to Java console. I was getting the following error each time I tried to run their Java console:

"unsigned application requesting unrestricted access to system"

I tested Java 1.8, 1.7, 1.6, 1.5 and 1.4 and all failed to run spider.jnlp file of Latronix KVM and returned the above error. There was a fix suggested to run it using Java however it did not work for me either.

I managed to mount ISO image to the VM by using Latronix KVM client software SpiderView which can be downloaded on their website.

Sunday, March 1, 2020

How install Xfce4 and RealVNC on Centos 7

Xfce is a lightweight desktop environment and it's a good choice as a GUI for servers running Centos 7 . It can be installed by using the following command :

yum groupinstall "Xfce" -y

However Xfce does not start properly with RealVNC on Centos 7. The following commands are needed to fix the problem according to RealVNC website :

Create a file called /etc/vnc/xstartup.custom and make it executable (chmod +x) with the following content :

#!/bin/sh
DESKTOP_SESSION=xfce
export DESKTOP_SESSION
startxfce4
vncserver-virtual -kill $DISPLAY


Create another file called /etc/vnc/config.custom and add the following commands :

-extension RENDER


and finally use this guide to fix "xfce GDBus.Error:org.freedesktop.PolicyKit1.Error.Failed: User of caller and user of subject differs." error on xfce startup.

Friday, November 22, 2019

How to Proxy SSL IMAP/POP3/SMTP using HAProxy and Dovecot+Postfix

This post shows how to configure a mail proxy server to connect clients in an intranet to an external mail server. I will use SSL offloading method since the mail proxy server is owned by the same company that's running the main mail server therefore decrypting the data on the proxy server and encrypting them again is not a security concern.

HAProxy - Dovecot configuration

I use HAProxy on the VPS Proxy server to proxy SSL IMAP/POP3/SMTP protocols to the main mail server. The main server is using Dovecot/Postfix to run email service.

First, install HAProxy on the VPS proxy server, generate a valid SSL for its hostname and configure haproxy to proxy IMAP/POP3/SMTP SSL ports to the main mail server :

listen main-pop3
  bind :995 ssl crt /etc/letsencrypt/live/HOSTNAME/fullchainkey.pem no-sslv3
  mode tcp
  balance first
  stick store-request src
  stick-table type ip size 200k expire 15m
  server s1 MAINHOST.FQDN:10110 send-proxy-v2 ssl verify required ca-file ca-certificates.crt

listen main-imap
  bind :993 ssl crt /etc/letsencrypt/live/HOSTNAME/fullchainkey.pem no-sslv3
  mode tcp
  balance first
  stick store-request src
  stick-table type ip size 200k expire 15m
  server s1 MAINHOST.FQDN:10143 send-proxy-v2 ssl verify required ca-file ca-certificates.crt

listen main-smtp
  bind :465 ssl crt /etc/letsencrypt/live/HOSTNAME/fullchainkey.pem no-sslv3
  mode tcp
  stick store-request src
  stick-table type ip size 200k expire 15m
  server s1 MAINHOST.FQDN:10465 send-proxy-v2 ssl verify required ca-file ca-certificates.crt

/etc/letsencrypt/live/HOSTNAME/fullchainkey.pem is a valid certificate generated for the VPS Proxy hostname and it should contain both private key and certificate.

MAINHOST.FQDN is the full hostname of the main mail server, and haproxy is connecting to it securely (send-proxy-v2 ssl) and verifying its SSL against ca-certificates.crt file.

Now, on the main mail server side, we need to configure dovecot to listed on the custom ports for haproxy (10110, 10143, 10465) . Dovecot added support for haproxy since version 2.2.19. We open separate ports for haproxy and enable haproxy in the listeners which will allow dovecot to get the correct data of clients from haproxy server. Add the following code to /etc/dovecot/conf.d/haproxy.conf on the main mail server:

haproxy_trusted_networks = VPS.PROXY.IP/32
service pop3-login {
   inet_listener pop3_haproxy {
     port = 10110
     haproxy = yes
     ssl = yes
   }
}
service imap-login {
  inet_listener imap_haproxy {
    port = 10143
    haproxy = yes
    ssl = yes
  }
}
service submission-login {
  inet_listener submission {
    port = 10465
    haproxy = yes
    ssl = yes
  }
}
submission_relay_host = localhost
submission_relay_port = 25
submission_relay_trusted = yes
submission_client_workarounds = whitespace-before-path

Note that we are not sending queries from haproxy directly to postfix, instead we use submission listener of dovecot to authenticate clients in a similar way as imap/pop3 protocols. To enable submission service, you need to add submission in the list of protocols in dovecot.conf file : 

protocols = imap pop3 submission

Dovecot receives emails on port 10465 from haproxy, authenticate clients using its configured settings, and then send them to submission_relay_host which is postfix in this case. Postfix is running on the same machine as dovecot on port 25. We need to configure postfix to accept XCLIENT data that dovecot sends to it. (Xclient contains data of client that haproxy sends to dovecot). We set dovecot to send the real data of client to postfix by setting submission_relay_trusted = yes in its config file. We also need to set postfix to accept this data from dovecot by adding the following line to /etc/postfix/main.cf file : 

smtpd_authorized_xclient_hosts = 127.0.0.1

Now, clients in a restricted network can connect securely to the VPS proxy server. This Proxy server receives data from clients and sends them securely to the main mail server.

The line submission_client_workarounds = whitespace-before-path is required in configuration of dovecot submission for Microsoft outlook to work properly. I was getting the following error in Microsoft outlook 2016 before setting this variable :

Sending reported error (0x800CCC78): Cannot send the message. Verify the e-mail address in your account properties. The server responded: 501 5.5.4 Invalid FROM: Unexpected whitespace before path

How to Stream RTSP / Webcam / IP Camera Over the Web

I had a Hikvision IPC-B120 that provides a simple RTSP stream, which I could view in VLC. I also wanted to see my Logitech BRIO’s feed in a ...