Author Archives: jan

Reverse SSH tunnel

Access Linux SSH server behind NAT via reverse SSH tunnel on relay server

• You have your Linux server running at home behind a NAT router without public IP address.
• You want to SSH to the home server from outside Internet.
• SSH port forwarding is not an option in this case.
• You don’t have your own public IP and you share some IP address with other users behind NAT.

The solution is reverse SSH tunneling.
• You need another relay host outside your network (for example VPS), which you can connect to via SSH.
• Then you set up a persistent SSH tunnel from the server in your home network to the public relay host.
• With this settings, you can connect back to your home server via the relay host.

Linux SSH server behind NAT: root@home-server
Relay SSH host (VPS): (public IP:
Your SSH client: username@laptop

Allow SSH daemon to port forward from external network interface (not only loopback) on SSH relay host.
[ ~]# vi /etc/ssh/sshd_config

GatewayPorts clientspecified

Restart SSH daemon.
[ ~]# /etc/init.d/ssh restart

Allow incoming port range on SSH relay host and autossh monitoring ports:
[ ~]# ufw allow 20001:20010/tcp
[ ~]# ufw allow 21001:21010/tcp

Create user account on relay server for SSH connection.
[ ~]# useradd -m -c "Name Surname" relay_username

Exchange the public key, the SSH connection works passwordless.
[root@home-server: ~]# ssh-copy-id

If you don’t have SSH keys generated yet, create them.
[root@home-server: ~]# ssh-keygen

Connect from your Linux server behind NAT using SSH relay host IP address and credentials (for example on VPS).
[root@home-server: ~]# ssh -N -R

On SSH relay host check if SSH tunnel is established successfully.
[ ~]# netstat -nap | grep 20001

Now, from your client laptop, you can access your home server behind NAT.
[username@laptop: ~]$ ssh -p 20001

Locate testing session on relay server.
[ ~]# netstat -nap | grep 20001

tcp        0      0*               LISTEN      24823/sshd: relay_username

Kill testing session identified by PID, in our example 24823.
[ ~]# kill 24823

Configure persistent reverse SSH tunnel by installing AutoSSH.
[root@home-server: ~]# apt-get install autossh

Test the connection with AutoSSH.
[root@home-server: ~]# autossh -M 21001 -N -T -q -o "PubkeyAuthentication=yes" -o "StrictHostKeyChecking=false" -o "PasswordAuthentication=no" -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -R

“-M 20001” heartbeat port on relayserver to monitor SSH session
“-N” open the connection and do nothing (not interactive)
“-T” disable pseudo-terminal allocation
“-q” quiet mode
“PubkeyAuthentication” use key authentication
“StrictHostKeyChecking” does not accept unknown SSH host keys automatically
“ServerAliveInterval” exchange keep-alive messages every 60 seconds
“ServerAliveCountMax” send 3 keep-alive messages without receiving any response back

Start AutoSSH during boot with systemd:

Description=AutoSSH tunnel service

ExecStart=/usr/bin/autossh -M 21001 -N -T -q -o "PubkeyAuthentication=yes" -o "StrictHostKeyChecking=false" -o "PasswordAuthentication=no" -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -R


Reload systemd and start AutoSSH daemon:
[root@home-server: ~]# systemctl daemon-reload && systemctl start autossh.service

Check AutoSSH the status.
[root@home-server: ~]# systemctl status autossh

Enable AutoSSH start during boot.
[root@home-server: ~]# systemctl enable autossh.service via OpenVPN

Privacy using OpenVPN and service

Let’s poke one’s prying eyes on your Internet traffic and setup VPN client to connect whole your home network (LAN) to Virtual Private Network using provider.

Install OpenVPN on your favorite distribution:
apt-get install openvpn

Generate OpenVPN client configs and OpenVPN keys for your account: Profile

Copy client configs and keys to /etc/openvpn/username.[ovpn,key,crt],ca.crt

Remove passphrase from private key:

openssl rsa -in username.key -out
mv username.key

Rename all *.ovpn profiles to *.conf:
rename "s/ovpn/conf/" *.ovpn

Autostart my OpenVPN server and client, edit /etc/default/openvpn:

AUTOSTART="server cz1-username"

Forward traffic through tun0 (OpenVPN):


Route incoming traffic via Internet original IP and gateway (eth0):
Server Fault solution

ip rule add from table 128
ip route add default dev eth0 via table 128

If you forward some traffic, for example port 10000:
-A PREROUTING -i eth0 -p tcp --dport 10000 -j DNAT --to-destination

You need to add another routing rule to return traffic to original source interface:

ip rule add from table 199
ip route add default dev eth0 via table 199

Set DNS server to Coolhousing ( for DNSmasq in /etc/resolv.dnsmasq:

Restart services:
/etc/init.d/dnsmasq restart
/etc/init.d/openvpn restart

Automounting NFS network shares

Automounting network shares when they are accessed or removable media when they are inserted. As I like NFS, this is my preffered solution, better then my old article using fstab.

Arch Linux
Red Hat
Server World

aptitude -y install autofs

AutoFS uses template files for configuration which are located in /etc/autofs. The main template is called auto.master, which can point to one or more other templates for specific media types.

You can configure autofs to mount your media to a specific folder (/-), rather than inside a common folder (/media).


#/media /etc/autofs/
/-    /etc/auto.mount


# create new: [mount point] [option] [location]
/disk -fstype=nfs,rw,rsize=8192,wsize=8192,timeo=14,intr

Restart AutoFS daemon:
systemctl restart autofs

Check if NFS export is mounted:
mount | grep /disk

Postfix SPF, DKIM and DMARC on Debian

Explanation of terms.

SPF (Sender Policy Framework) is a DNS text entry which shows a list of servers that should be considered allowed to send mail for a specific domain.

DKIM (DomainKeys Identified Mail) should be instead considered a method to verify that the messages’ content are trustworthy, meaning that they weren’t changed from the moment the message left the initial mail server. This additional layer of trustability is achieved by an implementation of the standard public/private key signing process.

DMARC (Domain-based Message Authentication, Reporting and Conformance) empowers SPF and DKIM by stating a clear policy which should be used about both the aforementioned tools and allows to set an address which can be used to send reports about the mail messages statistics gathered by receivers against the specific domain.

Installation and configuration process.

Install opendkim package
apt-get install opendkim opendkim-tools

Generate Key Pair
Following commands will generate two keys default.private and default.txt only for signing DKIM messages (-r).
mkdir -p /etc/mail/dkim-keys/$MYDOMAIN
cd /etc/mail/dkim-keys/$MYDOMAIN
opendkim-genkey -b 2048 -r -s mail -d $MYDOMAIN

Configure SPF, DKIM and DMARC for Postfix
Remember to add user postfix to group opendkim.
usermod -a -G opendkim postfix

DKIM configuration file

KeyTable           refile:/etc/mail/keytable
SigningTable       refile:/etc/mail/signingtable
Selector           mail
Socket             inet:8892@localhost
Canonicalization   relaxed/simple

Set correct access rights to /etc/mail folder
chmod 755 /etc/mail




Set opendkim user as owner of new files:
chown -R opendkim:opendkim /etc/mail/dkim-keys /etc/mail/keytable /etc/mail/signingtable

Postfix configuration file

milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:8892
non_smtpd_milters = inet:localhost:8892

Configure DNS Entry
SPF record
Add a TXT record to your domain with the following value:

v=spf1 mx a ptr ip4: ip4: ip4: ip4: ip4: ~all

DKIM record
Add a TXT record to your found in: /etc/mail/dkim-keys/ Omit the quotes and the text before and after quotes.

v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx+PJoQrLmluDH5gvtkY+aYNr5SXGqADVIBrZJFMBLJ4iEkUkC2285S1ivNH9Ly+REAoiP8S8VQPAStvvVSGgQFQopaxGYvEzJIrs+x3P/aTWa0nZjeBwEaQIVWMiDx4HCMV9YZ/SLCsCuiLzmpkxAKJ0kih+bUby6GYTgQScoBidKPYIfXtiVCaEoNYu9hcrHwsLHCp5Z3krvjHEPhlCuD416v5J2XbKJi+Q6RwCSoFkcGa5Y7SNx9/igIlhctzV636dMBe1E5X6T7WA+J6HDJXxSsQyiAUWKrzJH23vhdBDAwKiQp+8vF5gGdtvLJoUBhnYideZQFlfuVdNumvkzQIDAQAB

DMARC record
Be sure you have a DKIM and SPF set before using DMARC.
Add a TXT record to your domain with the following value:

v=DMARC1; p=none

Verify your SPF and DKIM records
dig TXT
dig TXT
dig TXT
Or use following service.

Test the keys for correct signing and verification (result should be “key OK“) after DNS records were updated using:
opendkim-testkey -vvv -d -s mail -k /etc/mail/dkim-keys/

Or use following service.

Restart Services
service opendkim restart
service postfix restart

Verify DKIM
Send a test email through command line:
mail -vs "Test DKIM" < /dev/null
In received email source search for “DKIM-Signature“.

Or use following service.

Raspberry Pi as WiFi Hotspot

MINImal raspBIAN image for Raspberry Pi (Minibian)

What you need

  • Minibian (Debian Jessie 8) 2016-03-12
  • Dnsmasq as DNS and DHCP server (already running in my network)
  • Raspberry Pi Model B (Rev 1.0, 256Mb)
  • 5V 2A microUSB power adapter
  • 8GB microSD card
  • Ethernet cable
  • Edimax EW-7811Un N150 Wireless USB Adapter Nano (RTL8192CU chipset)

Download and copy Minibian

tar -zxvf 2016-03-12-jessie-minibian.tar.gz
dd bs=4M status=progress if=2015-11-12-jessie-minibian.img of=/dev/sdd

Start Raspberry Pi and login via SSH
ssh root@faix-pi
Login: root
Password: raspberry

Identify Raspberry Pi
cat /proc/cpuinfo

Install system core tools
apt-get install raspi-config apt-utils logwatch hwinfo ncdu logrotate lsof postfix vim htop iotop iftop screen mc curl usbutils

Change locales to en_US.UTF-8

dpkg-reconfigure locales

Set hostname
hostnamectl set-hostname faix-pi

Select timezone Europe/Prague
dpkg-reconfigure tzdata

Set NTP server

server home-server
systemctl ntp restart

mkdir /var/cache/logwatch
Detail = High

Software Configuration Tool
Change User Password
Expand Filesystem

Update the package lists and upgrade
apt-get update; apt-get -y dist-upgrade; apt-get -y autoremove

Install bridge-utils, hostapd and rng-tools
apt-get install bridge-utils hostapd rng-tools

Bridge the Network Connections

#loopback adapter
auto lo
iface lo inet loopback
#wired adapter
iface eth0 inet dhcp
auto br0
iface br0 inet dhcp
bridge_ports eth0 wlan0

Configure Hostapd


Enable and start random number generator

systemctl enable rng-tools
systemctl start rng-tools

Reboot Raspberry Pi

Test your configuration
hostapd -dd /etc/hostapd/hostapd.conf

Enable and start hostapd daemon

systemctl enable hostapd
systemctl restart hostapd

Edimax EW-7811Un N150 Wireless USB Adapter Nano (RTL8192CU chipset)
hwinfo --wlan

02: USB 00.0: 0282 WLAN controller
[Created at usb.122]
Unique ID: BobO.Lnd5h7NE8EA
Parent ID: ADDn.GVovileGj8F
SysFS ID: /devices/platform/soc/20980000.usb/usb1/1-1/1-1.2/1-1.2:1.0
SysFS BusID: 1-1.2:1.0
Hardware Class: network
Model: "Realtek 802.11n WLAN Adapter"
Hotplug: USB
Vendor: usb 0x7392 "Realtek"
Device: usb 0x7811 "802.11n WLAN Adapter"
Revision: "2.00"
Serial ID: "00e04c000001"
Driver: "rtl8192cu"
Driver Modules: "8192cu"
Device File: wlan0
Features: WLAN
Speed: 480 Mbps
HW Address: 74:da:38:8c:3d:04
Link detected: yes
WLAN channels: 1 2 3 4 5 6 7 8 9 10 11 12 13
WLAN frequencies: 2.412 2.417 2.422 2.427 2.432 2.437 2.442 2.447 2.452 2.457 2.462 2.467 2.472
WLAN bitrates: 1 2 5.5 11
WLAN encryption modes: TKIP CCMP
WLAN authentication modes: open wpa-psk wpa-eap
Module Alias: "usb:v7392p7811d0200dc00dsc00dp00icFFiscFFipFFin00"
Driver Info #0:
Driver Status: 8192cu is active
Driver Activation Cmd: "modprobe 8192cu"
Config Status: cfg=new, avail=yes, need=no, active=unknown
Attached to: #4 (Hub)

OwnCloud Let’s Encrypt certificate renewal

I use OwnCloud with Let’s Encrypt certificate and recently I received error message below from my ctrontab command:

./letsencrypt-auto renew

All renewal attempts failed. The following certs could not be renewed: /etc/letsencrypt/live/ (failure)
1 renew failure(s), 0 parse failure(s)

WARNING: certbot.renewal:Attempting to renew cert from /etc/letsencrypt/renewal/cloud.conf produced an unexpected error: At least one of the (possibly) required ports is already taken. Skipping.

Failed authorization procedure. The client lacks sufficient authorization. Invalid response from

I have launched same command manually and error message clearly said again “unauthorized”.

Type: unauthorized
Detail: Invalid response from
Not Found

I found the solution on OwnCloud Forums. The point is to rewrite request to acme-challenge file from HTTPS to clear HTTP.

mkdir /var/www/owncloud/.well-known/acme-challenge
chmod 755 /var/www/owncloud/.well-known/acme-challenge/

vi /var/www/owncloud/.well-known/acme-challenge/.htaccess

RewriteRule ^\.well-known/acme-challenge letsEncrypt.php
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

chmod 644 /var/www/owncloud/.well-known/acme-challenge/.htaccess

Now you can launch ./letsencrypt-auto renew from cron without any issues.

Let’s Encrypt with Apache on Ubuntu

Clone the Let’s Encrypt repository
sudo git clone /opt/letsencrypt

Access the letsencrypt directory
cd /opt/letsencrypt

Auto install all dependencies

sudo -i

Generate certificates for your domains

Execute the interactive installation and obtain a certificate for each domain.

./letsencrypt-auto certonly --webroot -w /var/www/faix/wordpress/ -d -d
./letsencrypt-auto certonly --webroot -w /var/www/zviretnik/wordpress/ -d -d
./letsencrypt-auto certonly --webroot -w /var/www/owncloud/ -d -d
./letsencrypt-auto certonly --webroot -w /var/www/faix/wordpress/ -d
./letsencrypt-auto certonly --webroot -w /var/www/sikora/Gallery/ -d
./letsencrypt-auto certonly --webroot -w /var/www/silhavy/gallery/ -d
./letsencrypt-auto certonly --webroot -w /var/www/martinek/ -d
./letsencrypt-auto certonly --webroot -w /var/www/smrtak/gallery/ -d

First time you will be asked to provide an email address for lost key recovery and notices:

You can find the generated certificate files at:

Certificate Auto Renewal

Edit the crontab to create a new job that will run this command every week.

crontab -e

00 2 * * 1 /opt/letsencrypt/letsencrypt-auto renew >> /var/log/le-renew.log

Apache SSL configuration


SSLCertificateFile /etc/letsencrypt/live/
SSLCertificateKeyFile /etc/letsencrypt/live/
SSLCertificateChainFile /etc/letsencrypt/live/

SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on
SSLVerifyClient none
SSLVerifyDepth 1
SSLCompression off

Update Let’s Encrypt Client

cd /opt/letsencrypt
sudo git pull

Enable init.d scripts on Cyanogenmod 12

On my phones I want to have mount point directory /mnt/disk, because I like to use SSHFSAndroid to mount my server shares to this location.

By default, init.d is not enabled on Cyanogenmod 12 or 12.1.

Thanks to Ryuinferno @ XDA, there is a simple way to enable init.d again.

1. Download script, extract it and put on the root of your SD card.

2. Install a Terminal Emulator and Busybox.

3. Open the Terminal application and then issue the following commands:

cd /sdcard/

4. Reboot and check if file /data/Test.log exists. If yes, init.d works on your phone.

5. You can use /system/etc/init.d/80DiskMountPoint script, to create /mnt/disk mount point every boot of your device.

If not, you will have to run Uni-init, Term-init or Zip-init from this XDA article.

BTW, you can control init.d and many other Kernel settings using Kernel Adiutor.

merge multiple JPG to PDF

Have you ever wated to create PDF file from multiple JPG images from Linux command line?

It is simple, just type:
convert `ls -v *.JPG` output.pdf

The convert command is part of imagemagick package. In Debian / Ubuntu / Mint you can install it via command:

apt-get install imagemagic

Ntopng on Debian

Here is description how to install Ntopng on Debian.

ntopng” is an open-source network traffic monitor that shows the network usage, the next generation version of the original ntop.

NEW ntopng v2.4.1

ntopNG Debian repository.

Debian 7 (wheezy)

dpkg -i apt-ntop-stable.deb
grep -q "wheezy-backports" /etc/apt/sources.list || echo "deb wheezy-backports main" >> /etc/apt/sources.list

Debian 8 (jessie)

dpkg -i apt-ntop-stable.deb

apt-get clean all
apt-get update && apt-get upgrade
apt-get install pfring ntopng ntopng-data n2disk



OLD ntopng v1.2.1

1. Install dependencies
apt-get install autoconf automake autogen libsqlite3-dev libhiredis-dev libtool rrdtool libpcap-dev libglib2.0 libglib2.0-dev libgeoip-dev redis-server wget libxml2-dev build-essential checkinstall

2. Download ntopng

sudo -i
cd /usr/local/src
wget --trust-server-names

3. Compile ntopng (with geoip database)

tar -zxvf ntopng-1.2.1.tgz
cd ntopng-1.2.1
make geoip

4. Create .deb package

The package documentation directory ./doc-pak does not exist. 
Should I create a default set of package docs?  [y]: y

Answer: y

Please write a description for the package.
End your description with an empty line or EOF.
>> ntopng

Type "ntopng".

Continue by pressing ENTER.

New package was automatically installed to your system!

You can remove it using: dpkg -r ntopng

The new package should be located in ntopng folder e.g:

5. Configure ntopng init script

Create ntopng configfile in /etc/default folder and create new folder for logs:

mkdir /var/lib/ntopng
mkdir /var/log/ntopng
touch /var/log/ntopng/startup.log
touch /etc/init.d/ntopng
chmod +x /etc/init.d/ntopng

vi /etc/init.d/ntopng

#! /bin/sh
# Provides: ntopng
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start ntopng daemon
# Description: Enable services provided by ntopng

DESC="network top daemon"
# The current version of ntopng always creates the pidfile in /var/tmp/

test -f $DAEMON || exit 0

. /lib/lsb/init-functions

test -f $INIT || exit 0


[ "$ENABLED" = "0" -o "$ENABLED" = "no" -o "$ENABLED" = "n" ] && exit 0

ARGS="--daemon --pid $PIDFILE"

if [ -n "$INTERFACES" ]; then
 for i in $INTERFACES; do
 ARGS="$ARGS -i $i"

if [ -n "$HTTP_PORT" ]; then


ntop_start() {
 /sbin/start-stop-daemon --start --quiet --name $NAME --pidfile $PIDFILE \
 --exec $DAEMON -- $ARGS \
 > /var/log/ntopng/startup.log 2>&1
 if [ "$retval" -eq 1 ]; then
 log_progress_msg "already running"
 return 0
 return $retval

ntop_stop() {
  /sbin/start-stop-daemon --stop --quiet --oknodo --name $NAME --exec $DAEMON --retry 9 --pidfile $PIDFILE
  return $?

case "$1" in
    log_daemon_msg "Starting $DESC" "$NAME"
    if ntop_start; then
    log_daemon_msg "Stopping $DESC" "$NAME"
    if ntop_stop; then
  restart | force-reload)
    log_daemon_msg "Restarting $DESC" "$NAME"
    if ntop_stop && ntop_start; then
  reload | try-restart)
    log_action_msg "Usage: $SCRIPTNAME {start|stop|restart|force-reload|status}"

exit 3
 status_of_proc $DAEMON $NAME
 log_action_msg "Usage: $SCRIPTNAME {start|stop|restart|force-reload|status}"
 exit 1

exit 0

Create a symlink to init script to start the daemon automatically:
update-rc.d ntopng defaults

vi /etc/default/ntopng

#Configure network interfaces e.g:.
INTERFACES="eth0 br0"
#Port on which ntopng will listen for the web-UI - default port 3000.
#Additional command-line arguments for ntopng, more: ntopng --help.

6. Start redis-server and ntopng daemons

/etc/init.d/redis-server restart
/etc/init.d/ntopng start

ntopng should listen on TCP/3000 port. Verify this using:
netstat -tlpn | grep ntopng

tcp        0      0  *               LISTEN      23285/ntopng

Verify the log for possible errors:
less /var/tmp/ntopng/ntopng.log

7. Accesss to Ntopng:

Username: admin
Password: admin