- Showing all posts in category: Linux
# Using SDKMan with Oracle JDK
Published on 20-10-2019

SDKMAN! does not distribute any Oracle JDK anymore. I think they stopped providing it for a while now(see their Medium article). I am used with the way of having multiple JDK versions managed by SDKMAN! and just switch between version using one command.

For my current project I have to use a certain Oracle JDK version, which is been installed locally on my machine, but I want to have it managed by SDKMAN!. Fortunately you can add your local JDK version by using the local install feature:

sdk install java 10-zulu /Library/Java/JavaVirtualMachines/zulu-10.jdk/Contents/Home


More info: SDKMAN! Local installation

It suprises me that some fellow developers that still struggle installing some development kits like Java JDK, Maven. It might be a pain in the ass to find your right piece of software for yourLinux distribution. How many times did you had a bug, or you were missing some feature that is released in a newer version but yet it was not available in your repo?

 Especially when you need to be able to switch between versions because because of multiple projects you have to find a way to manage these multiple versions.

The moments when Maven could not build your project because you were using JDK8 instead of 11. I'm not only talking about Java, but also with tools like Maven, Gradle, Kotlin etc.

When installing Java JDK on Linux by using your package manager of your OS, you might encounter some difficulties. Finding the right version is one of the struggles, but if you install multiple versions, you have to tell your OS which version you prefer to use. You would do this by configuring the update-alternatives. Besides that, you have to modify your $JAVA_HOME environment variable. Everytime you want to switch versions, you have to configure update-alternatives and change your $JAVA_HOME. And everytime you are Googling how to switch those damn versions.

SDKMAN! comes to the resque!
"SDKMAN! is a tool for managing parallel versions of multiple Software Development Kits on most Unix based systems. It provides a convenient Command Line Interface (CLI) and API for installing, switching, removing and listing Candidates." SDKMAN

I am lazy. I am simple. I am using SDKMAN. Simply because the installation is just executing 1 line of code

$ curl -s "" | bash

The installation instructions are  here.

I mean, it is so easy. Do you want to know what versions of JDK you can install| 
Retrieve the list of available JDK.

gokhan@DESKTOP-0VOK5ER:~$ sdk list java
==== BROADCAST =================================================================
* 2019-06-24: Gradle 5.5-rc-4 released on SDKMAN! #gradle
* 2019-06-19: Kotlin 1.3.40 released on SDKMAN! #kotlin
* 2019-06-19: Springboot 2.1.6.RELEASE released on SDKMAN! #springboot
Available Java Versions
 Vendor        | Use | Version      | Dist    | Status     | Identifier
 AdoptOpenJDK  |     | 12.0.1.j9    | adpt    |            | 12.0.1.j9-adpt
               |     | 12.0.1.hs    | adpt    |            | 12.0.1.hs-adpt
               |     | 11.0.3.j9    | adpt    |            | 11.0.3.j9-adpt
               |     | 11.0.3.hs    | adpt    |            | 11.0.3.hs-adpt
               |     | 8.0.212.j9   | adpt    |            | 8.0.212.j9-adpt
               |     | 8.0.212.hs   | adpt    |            | 8.0.212.hs-adpt
 Amazon        |     | 11.0.3       | amzn    |            | 11.0.3-amzn
               |     | 8.0.212      | amzn    |            | 8.0.212-amzn
 Azul Zulu     |     | 12.0.1       | zulu    |            | 12.0.1-zulu
               |     | 11.0.3       | zulu    |            | 11.0.3-zulu
               |     | 10.0.2       | zulu    |            | 10.0.2-zulu
               |     | 9.0.7        | zulu    |            | 9.0.7-zulu
               |     | 8.0.212      | zulu    |            | 8.0.212-zulu
               |     | 7.0.222      | zulu    |            | 7.0.222-zulu
               |     | 6.0.119      | zulu    |            | 6.0.119-zulu
 Azul ZuluFX   |     | 11.0.2       | zulufx  |            | 11.0.2-zulufx
               |     | 8.0.202      | zulufx  |            | 8.0.202-zulufx
 BellSoft      |     | 12.0.1       | librca  |            | 12.0.1-librca
               |     | 11.0.3       | librca  |            | 11.0.3-librca
               |     | 8.0.212      | librca  |            | 8.0.212-librca
 GraalVM       |     | 19.0.2       | grl     |            | 19.0.2-grl
               |     | 19.0.0       | grl     |            | 19.0.0-grl
               |     | 1.0.0        | grl     |            | 1.0.0-rc-16-grl      |     | 14.ea.2      | open    |            | 14.ea.2-open
               |     | 13.ea.26     | open    |            | 13.ea.26-open
               |     | 12.0.1       | open    |            | 12.0.1-open
               |     | 11.0.2       | open    |            | 11.0.2-open
               |     | 10.0.2       | open    |            | 10.0.2-open
               |     | 9.0.4        | open    |            | 9.0.4-open
 SAP           |     | 12.0.1       | sapmchn |            | 12.0.1-sapmchn
               |     | 11.0.3       | sapmchn |            | 11.0.3-sapmchn
Use the Identifier for installation:

    $ sdk install java 11.0.3.hs-adpt


For example we want to install OpenJDK 12.0.1

gokhan@DESKTOP-0VOK5ER:~$ sdk install java 12.0.1-open

Downloading: java 12.0.1-open

Repackaging Java 12.0.1-open...

Done repackaging...

Installing: java 12.0.1-open
Done installing!

Setting java 12.0.1-open as default.


To use java 12.0.1 as default:

sdk default java 12.0.1-open


List all available canidates:

gokhan@DESKTOP-0VOK5ER:~$ sdk list

Available Candidates
q-quit                                  /-search down
j-down                                  ?-search up
k-up                                    h-help

Ant (1.10.1)                                   

Apache Ant is a Java library and command-line tool whose mission is to drive
processes described in build files as targets and extension points dependent
upon each other. The main known usage of Ant is the build of Java applications.
Ant supplies a number of built-in tasks allowing to compile, assemble, test and
run Java applications. Ant can also be used effectively to build non Java
applications, for instance C or C++ applications. More generally, Ant can be
used to pilot any type of process which can be described in terms of targets and

                                                               $ sdk install ant



Find more about the usage on the SDKMAN! website.


Unfortunately it does not provide NodeJS. You could use NVM for that


# Rm: Argument list too long
Published on 13-07-2018


There is a Dutch saying: "Bij de loodgieter lekt de kraan", which literally means "The tap is leaking at the plumbers home"

My security camera records pictures and video's into my NAS server. One in a while I have to truncate the directory because it's not accessible anymore through CIFS. Within 3 months there are more than 100k files. I do this manually because I'm lazy.

Usually you will go away with just executing the rm command. But with a huge number of files you get this message:

root@nas:/mnt/Data # rm -rf dvr/*
/bin/rm: Argument list too long.

The reason you get this message is because it's a kernel limitation. You can find out the maximum number of arguments that your kernel supports with this command:

getconf ARG_MAX

The solution

Use a for loop within the current directory:

for f in *.png; do rm "$f"; done

Use find:

#To delete .png files within the current directory
find . -name ".png" -exec rm {} +

#Delete everything within the current directory
find . -name ".png" -exec rm {} +

Source: Stackoverflow


On proxmox I was getting this error when connecting through SSH

perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
    LANGUAGE = (unset),
    LC_ALL = (unset),
    LANG = "en_US.UTF-8"
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").

Has to do with some locale that can't be loaded.


Remove/Comment this line in /etc/ssh/sshd_config:

AcceptEnv LANG LC_*

Restart SSHD

Yep, Today was my day. Sometimes I forget to load my private key to connect with the server and I get rejected. This accumulates the authentication errors and ta da, I get locked out after the 3rd time. Denyhosts keeps track of the number of authentication attempts and adds the IP on the /etc/hosts.deny file.

DenyHosts is a script intended to be run by Linux system administrators to help thwart SSH server attacks (also known as dictionary based attacks and brute force attacks).
Bot's are scanning the internet and trying to make attempts to login. Take a look at your auth log file and you will see many attempts, with many I mean  many PER SECOND!

When I take a look at my /etc/hosts.deny file I see my own IP.  After removing my IP it will be put back with the next login attempt. What the hell?

Denyhosts stores the IP addresses also in these files listed below. Make sure you check them all and remove when necessary. 

But first stop denyhosts using this command

systemctl stop denyhosts.service

systemctl start denyhosts.service


Always disable password authentication in SSHD. Instead use public key authentication. It's more convenient and more secure. But be careful with your private key.

# SVN commit deleted files
Published on 12-03-2017

Command to prepare svn to add your deleted files to commit:

svn st | grep ^! | awk '{$1=""; print " --force \""substr($0,2)"@\"" }' | xargs svn rm


A handy package to search through indexed files is mlocate which you will get bundled in a server or workstation installation of a Linux operating system.

The first time you will always get this error:

[root@puppetmaster manifests] locate "site.pp"
locate: can not stat () `/var/lib/mlocate/mlocate.db': No such file or directory

This means that the file mlocate.db is missing because the file index database has never been builded before.

Run this command to build the file index database:

[root@puppetmaster manifests] updatedb

You also can run this command to update the database.

Note that it could take a while to build the database.

Somebody at GNOME decided to make the second monitor to stay fixed when you switch workspaces. To enable the switching  workspaces of the  second monitor, change this gnome setting by running this command. 

gsettings set workspaces-only-on-primary false

Note: With older versions of GNOME you may need to use gconf-editor.

In GNOME 3.8 you can switch workspace by using the Super + Page Up or Super + Page Down. Unfortunately you can do the same with Ctrl + Alt + Arrow Up or Ctrl + Alt + Arrow Down.  The last one conflicts with a neat shortcut in Eclipse to duplicate lines.

Under Settings > Keyboard you will find the hotkey to switch workspaces. The Ctrl + Alt Arrow Up/Down is always bound and is not shown.

Check which keys are bound here:

gsettings get org.gnome.desktop.wm.keybindings switch-to-workspace-up
['<Super>Page_Up', '<Control><Alt>Up']

gsettings get org.gnome.desktop.wm.keybindings switch-to-workspace-down
['<Super>Page_Down', '<Control><Alt>Down']

You can clearly see that both commands have 2 hotkeys assigned.

To remove the Ctrl + Alt variant run this:

gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-down '["<Super>Page_Down"]'
gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-up '["<Super>Page_Up"]'

The hotkeys Super + Page Up and Super + Page Down are retained but Ctrl + Alt + Arrow Up and Ctrl + Alt + Arrow Down are removed.

# Remove cached SVN credentials
Published on 10-11-2016

When using linux or OSX your SVN credentials are saved under your user profile. 

This happens when you use a IDE or using svn from commandline.

This message is shown then:

ATTENTION!  Your password for authentication realm:

   <https://domain.tld> Staff only

can only be stored to disk unencrypted!  You are advised to configure
your system so that Subversion can store passwords encrypted, if
possible.  See the documentation for details.

You can avoid future appearances of this warning by setting the value
of the 'store-plaintext-passwords' option to either 'yes' or 'no' in
Store password unencrypted (yes/no)? yes

Like it says, SVN stores your username and password in plain-text inside your user profile.

To remove all stored SVN username and passwords:

rm ~/.subversion/auth/svn.simple/*


The contents of a credential file looks like this:

K 8
V 6
K 8
V 7
K 15
V 41
<https://domain.tld> Staff only
K 8
V 6


Managing your linux machine from remote is a great thing, but you shouldn't allow root to logging in from SSH. Or at least when it's reachable from outside. There are anonymous groups active who will beat you up when when you allow this. Naah just a joke, I will beat you up personally. Or you could read this article.


Why shouldn't you allow root to logging in from SSH anyway?

Everyone knows that every Linux operating system has a user called 'root' who can do anything in the system. Root is the root. It can even take your dog away for a walk!

Because everyone knows that this user exists, they only need to guess the password to break in to your system by doing a brute force attack. So someone starts some script or bot who will do continuously login attempts with generated passwords. So the first thing you need to do is disallowing root access. Or even better, have a white list with IP addresses where you will allow SSH connections from.  Or if this is not an option, just block IP addresses where many unsuccessful login attems are made.I will write an article about that too but in the meanwhile take a look at DenyHosts.

So we are going to disallowing the root user to logging in from SSH.

Open the sshd_config file:

sudo vim /etc/ssh/sshd_config


Look for this line:

#PermitRootLogin no

After a clean install you would see that this line is usually commented. This means it will use the default value with is be YES. So having this line commented means that you will allow root login. Holy shit bro, look out I might stand behind you with a baseball bat!

Just change this line into:

PermitRootLogin no

Restart sshd to apply the changes:

sudo /etc/init.d/sshd restart

So how are you supposed to login now? You need to have a normal user with administrator rights or adding the user into sudoers by using visudo. Don't edit the /etc/sudoers file directly. Just do it with visudo because it will validate the changes you have done. if you screw this up, then sudo is not working properly.

# Proxmox 4.x enabling IP forwarding
Published on 21-05-2016

If you are upgrading your machine from Debian Wheezy to Jessie, then you will find out that there is no IP forwarding anymore. In my case I was upgrading my Proxmox 3.1 to 4.2 and masqerading with iptables. So having 1 public address for multiple virtual machines.

You have to check your  /etc/network/interfaces and add this line:

post-up echo 1 > /proc/sys/net/ipv4/ip_forward

This enables ip forwarding.

Should look like this:

auto lo
iface lo inet loopback

auto eth0
#real IP adress 
iface eth0 inet static

auto vmbr0
#private sub network
iface vmbr0 inet static
        bridge_ports none
        bridge_stp off
        bridge_fd 0

        post-up echo 1 > /proc/sys/net/ipv4/ip_forward
        post-up   iptables -t nat -A POSTROUTING -s '' -o eth0 -j MASQUERADE
        post-down iptables -t nat -D POSTROUTING -s '' -o eth0 -j MASQUERADE



# From a barebone to a PowerEdge
Published on 30-07-2015

It all started on my hobby barebone server. My goal was to learn setting up an webserver and to create some hobby websites on it. As a student, I bought an Asus Terminator T2-P deluxe.

The Asus Terminator T2-P deluxe had the following specs:

  • Socket 478 motherboard
  • Intel Celeron D 2.4 Ghz(after a while upgraded to a Pentium 4 3.06 Ghz)
  • 2x 1 GB DDR PC 3200
  • 1x 80 GB WD disk
  • 1x 1TB Samsung disk
  • Running Windows XP with Xampp and Webmin(yeah i know :'))


After my home server got hacked due to crappy security(who the hell allowes remote access to webmin), my server became a member of an botnet. This lasted a few days until my ISP disconnected me and send me a letter. The letter stated that there were illegal activities from my IP and that's why they kicked me off the internet.

It was time to try the real deal: FreeBSD. My first introduction to linux was FreeBSD. When I look back, it was the hardest distro ever, but it was the best way to start learning about UNIX systems. It took me around 4 reinstalls to learn about things I should do better the next time. I was running a Postfix mailserver with an open relay. There were around 40k mails send each day.

The next step into the UNIX systems was running CentOS. Like FreeBSD I was running Apache, PHP, Postfix, MySQL and Bacula on the same operating system. This setup wasn't reliable because as soon as one component crashes, everything crashes.

It became time to go enterprise. In 2010 I bought a Dell PowerEdge R210 with the following specs:

  • Intel Xeon 3430
  • 12GB RAM
  • 2x 500GB 7200Rpm WD RE


Colocated at Leaseweb at datacenter Evoswitch in Haarlem


After a year running CentOS colocated, I was interested in virtualisation. I've read about it and everyone talked about it like it was the answer to the meaning of life. Hell yeah, it was.

The first hypervisor I tried was ESXI. I bought a second hand Dell PowerEdge 1850 with 2x SCSI 72GB disks to try some things with ESXI. I became deaf with the server running in my room. There were also problems with the drivers. Because the PE 1850 was kinda old, I was forced to use an older version of ESXI and wasn't happy with the lack of a web interface. I sold the PE 1850.

Next thing I tried was Proxmox. This was the thing I was looking for: an opensource Debian based bare metal hypervisor. I couldn't install it on my colocated PowerEdge R210 because my mail and websites were running on it, so I made the decision to buy another Dell server.

The new Dell PowerEdge R310 server specs:

  • Intel Xeon 3430
  • 16GB RAM
  • 4x 500GB 7200 RPM WD RE
  • Dell Perc H200A

Well, the server was up and running Proxmox with 4 virtual machines and faced to next problem: the datacenter gave me 1 public IP. I have managed to make all virtual machines reachable behind 1 public IP.


The solution was using an virtual internal network between the virtual machines and Proxmox was configured to bridge incoming connections to the virtual firewall/router. This process is called NAT(Network Address Translation) and Masquerading.

All other virtual machines are behind the firewall/router. If the virtual machine running firewall/router is shut down, then all the underlying virtual machines are not reachable. Sounds secure to me. Every virtual machine I am running, has it's own responsibility. Like I said, running multiple 'servers' on one operating system is not reliable. So I have  virtual machine running only apache, the other vm is running MySql etc.

Why no VPS?

Well, I like to learn about managing my own server so I can do whatever I want. The only advantage you have with VPS is that you don't need to worry about the hardware of your server. If something gets broken, then it isn't your responsibility anymore.

VPS mostly have a limited choice of operating systems. Like I said before, It's not reliable to give one server/operating system many responsibilities.If you want to install a webserver, database and a mailserver on three seperate VPS'you will pay at least around €100,-.