Tuesday, May 25, 2021

Configuring OpenVPN with Ed25519 certificates and TLS 1.3

Creating certificates with Elliptic Curves: 

Requirements: OpenSSL 1.1.x, OpenVPN 2.5.x, EasyRSA 3.0.x

Initializing PKI environment

# easyrsa init-pki

Creating the Certificate of Authority (CA)

# easyrsa --use-algo=ed --curve=ed25519 build-ca

Creating Certificate Request

# easyrsa --use-algo=ed --curve=ed25519 --req-c=BG --req-city=Gabrovo --req-org=Horizon9 --dn-mode=org gen-req horizon9

Singning the CA request

# easyrsa sign-req server horizon9
Creating OpenVPN server keys
# easyrsa build-server-full horizon9 nopass

Creating OpenVPN client keys

# easyrsa build-client-full client1 nopass


OpenVPN config file:

local # put your IP address here
port 1194
proto tcp
dev tun
ca /path/to/ca.crt
cert /path/to/horizon9.crt
key /path/to/horizon9.key
server # your OpenVPN network IP addresses
push "route" # your local network here
push "dhcp-option DNS"
keepalive 5 120
status /var/log/openvpn-status.log
log-append  /var/log/openvpn.log
verb 4

#data channel cipher
cipher AES-128-GCM

#don't negotiate ciphers, we know what we want

# TLS 1.3 encryption settings
tls-ciphersuites TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256

# TLS 1.2 encryption settings

#disable static Diffie-Hellman parameters since we're using ECDHE
dh none

# use this curve
ecdh-curve secp384r1

#this tells OpenVPN which side of the TLS handshake it is

#tls-client # uncomment this on the client side

Friday, February 12, 2021

Converting CVS to GIT repositories

You need cvs-fast-export tool in your path
All projects in old CVS repositories are listed in all-projects.txt file and it is in you old cvs repos folder.

for a in `cat all-projects.txt`
    cd $a
    find .|cvs-fast-export > ~/separate-projects/$a.cfe
    cd ..
This will export every project folder as single file in /home/username/separate-projects/ 

Now to import it as git repositories

cd ~/separate-projects/
for a in `ls *.cfe`
adir=`echo $a|sed s/".cfe"/""/g`
    git init "$adir".git
    cd "$adir".git
    git fast-import < ../$a
    cd ..



Wednesday, May 13, 2020

DHCP server listen on alias interface (eth0:1)

Linux server with more than one IP address on the same interface.

eth0 -
eth0:1 -

We want DHCP server to serve IP addresses only from . If we do this in config file like this:

 subnet netmask {
                option broadcast-address;
                option routers;

it will fail to start and produce the following error:

dhcpd: No subnet declaration for eth0 (

The correct configuration is to use shared-network parameter and define all the networks of the physical interface inside it.

shared-network horizon9net {
        subnet netmask {

        subnet netmask {
                option broadcast-address;
                option routers;

Thursday, November 21, 2019

Novell OES 11.1 shell commands hang without reason

Novell OES 11 linux shell commands hang for a very long time. It happened to me and I was able to fix it without restarting the whole server.

Server release info:
Novell Open Enterprise Server 11 (x86_64)
VERSION = 11.1
# strace -p26881
Process 26881 attached - interrupt to quit
connect(146, {sa_family=AF_FILE, path="/var/run/novell-lum/.nam_nss_sock"}, 35^C <unfinished ...>
All http services that are not using linux authentiction are working - iManager works, iMonitor works, Remote Manager is not working because it is for controlling linux services and require linux authentication.

It seems that something went wrong with namcd service. Most linux commands (like cron, id, ssh...) are trying to check through that socket for a user FDN from eDirectory. Linux User Managment (LUM) maps linux users to eDirectory users and every linux program executed is asking namcd (eDirectory Novell Account Management caching daemon) for information about current user. If namcd is not working it will just use local linux user db for that and if is working correctly you can check every user in eDir like this:

Note: admin is not local linux user but eDir user

Working LUM and namcd:
# id admin
uid=602(admin) gid=602 groups=602,601(sms smdr group)
Not working LUM and/or namcd:
# id admin
id: admin: No such user
The problem is when namcd is working but not returning any data through that socket. Then you get every linux command that checks for current user to hang forever.
# id admin
(hangs forever until you press ctrl+c)
Solution is to kill all hanged processes and then restart namcd
# rcnamcd restart
I was able to login via ssh in a strange way - it asks me for password and then hanged and I left it like this and after an hour I pressed ctrl+c and it showed me the desired shell on the remote server.

If you do this and it still does not work properly and you get messages like this in /var/log/messages
Nov 22 10:19:45 storage /usr/sbin/namcd[720]:  GetGIDsGroupListNumberOfGroupsOfWS: Error [32] in LDAP search while trying to find group FDNs with scope=base for cn=UNIX Workstation - storage,o=servers
You need to recreate nam.conf. For more information look here:

Thursday, March 28, 2019

Poweshell OpenFIleDialog works in ISE but hangs when started from command line

This code works in Powershell ISE but when started from command line and OpenFileDialog is called it hangs
$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$OpenFileDialog.Title = "Please Select File"
$OpenFileDialog.InitialDirectory = $initialDirectory
$OpenFileDialog.filter = "TXT files (*.txt)| *.txt"
When we set .ShowHelp = $true it works
$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$OpenFileDialog.Title = "Please Select File"
$OpenFileDialog.InitialDirectory = $initialDirectory
$OpenFileDialog.filter = "TXT files (*.txt)| *.txt"
$OpenFileDialog.ShowHelp = $true
and I don't know why but it works!

Friday, February 1, 2019

Fast import of billion lines to postgresql

This is the fastest way I've found about importing huge (3+ billion lines) text files in csv-like format in PostgreSQL. It requires python3 and psycopg2

# initial stuff by Cac Ko <email@gdpr_protected_stuff> 
# additional by <>
# import very large cvs-like file in postgre database
# 01.02.2019
# requires psycopg2 postgresql lib for python
# file format is:
# ----------------------------
# something12:otherthing2345
# something7134:otherthing4243
# .....
# License: Public Domain

import os
import sys
import psycopg2
from psycopg2.extras import execute_values

# use file in tmpfs for faster read/write
POS_FILE = '/run/.position'

# get current position from POS_FILE location
def getPosition():
    result = 0
    if os.path.exists(POS_FILE):
        with open(POS_FILE, 'rb') as f:
                result = int(
                print("result = %d" % result)
            except Exception as error: 
                print("Error read():", error)
                result = 0
    return result

# write to this file after each commit()
def storePosition(pos):
    with open(POS_FILE, 'w') as f:

# uncomment the following 3 lines if you want perentage / position on stdout
#    y = pos/whole*100
#    print('{0:.2f}%'.format(y), end = '')
#    print(" pos=%s" % (str(pos)))

# store stuff in database
def storeInDb(line, bulk_data):
#    print(line)
    x = []
    x = line.split(':')
    sql = b'INSERT into secrets (somestuff1, somestuff2) VALUES %s'
        execute_values(cur, sql, bulk_data)
    except Exception as error:
        print("Error pri INSERT", error)

if __name__ == '__main__':
        if len(sys.argv) < 2:
            print('usage: ./ filename-to-import.csv')
        f = open(sys.argv[1], 'r', buffering=2000000, errors='replace')
        whole = os.path.getsize(sys.argv[1])
        pos = getPosition()
        print("Start reading from pos=%d" % pos)
        line = f.readline()
            bulk_count = 0;
            connection = psycopg2.connect(
                user="postgres", password="somestuff", host="", port="5433",
database="postgres") cur = connection.cursor() bulk_data = [] split_line = [] while line: split_line = line.split(':') try: l = tuple(split_line) bulk_data.append(l) except (Exception) as error: print(error) pass storePosition(f.tell()) line = f.readline() bulk_count = bulk_count + 1 # store and commit in db after X lines if bulk_count == 9000: storeInDb(line,bulk_data) bulk_count = 0; bulk_data = [] #connection.commit() except (Exception, psycopg2.Error) as error: print("Error while connecting to PostgreSQL", error) finally: if(connection): cur.close() connection.close() print("PostgreSQL connection is closed") except KeyboardInterrupt: storePosition(f.tell()) if(connection): cur.close() connection.close() print("PostgreSQL connection is closed")
I am too lazy to explain how this script works and probably there are some errors but it works for me.

Friday, January 4, 2019

xorg.conf ModeLine for VGA connected ViewSonic monitors

Even with latest Linux distributions you can face the problem of Xorg not detecting your monitor.

My monitor is ViewSonic VG2030wm and it is capable of working at 1680x1050 resolution but Xorg can't detect that and highest resolution that I can use is 1024x768.

You need to add ModeLine so the Xorg can recognize it. Here is my Monitor section from xorg.conf:

Section "Monitor"
        Identifier   "ViewSonic"
        VendorName   "ViewSonic"
        ModelName    "VG2030wm"
        HorizSync    24.0 - 92.0
        VertRefresh  50.0 - 85.0
        Option       "DPMS"
        ModeLine "1680x1050" 170.00 1680 1784 1960 2240 1050 1053 1059 1089 +hsync +vsync

Probably you will need just the ModeLine row but I am publishing the whole Monitor section.

You can find more ModeLine for certain monitors here: