Wednesday 21 December 2022

Fail2Ban on OpenBSD 7.1

Building on the Shoulders of Giants

My inspiration for using Fail2ban on OpenBSD was this post from Ismael J. Tisminetzky for OpenBSD 6.9. I was using sshguard, but I also wanted to protect other services like http and https, and sshguard is just not designed for that. I have been using fail2ban for a few years, and I just find it the right tool for the task of delaying script-kiddies-like attacks.

Thank you Ismael J. Tisminetzky!

Starting Point

The system is running OpenBSD 7.1, with nginx serving a typo3 site. with 4Gb RAM, 2 vCPUs. Not a great machine, but more than enough to play around. It's publicly accessible server, with the default ssh service which is constantly being hammered with all kinds of login attempts.

Fail2Ban Requirements

The current version hosted at Github is 1.0.2, and it requires:

Optional:

We first try it with python-3.10.8 but, after an unsuccessful attempt, I decide to try with python-3.9.15.

Bash should also be included in the requirements as most, if not all non-python scripts are for bash. We run, as root:

# pkg_add python-3.9.15
# ln -s /usr/local/bin/python3.9 /usr/local/bin/python
# git clone https://github.com/fail2ban/fail2ban.git

/usr/bin/bash

We need to add a link to bash on /usr/bin because the scripts we need to run expect it there.

# ln -s /usr/local/bin/bash /usr/bin/

Note: This may not be necessary, as we run all bash scripts by preceding the name of the script with "bash".

Locale

In one of my failed attempts, I observed some warnings about the locale. Unfortunately, the locale "en_IE.UTF-8" is not yet available for OpenBSD, so we set it to "en_GB.UTF-8" before running the setup script.

export LANG="en_GB.UTF-8"

Installing Fail2Ban

As recommended in multiple github issues, we better run the fail2ban-2to3 script from the cloned git repository:

# cd fail2ban
# bash fail2ban-2to3
RefactoringTool: Skipping optional fixer: buffer
RefactoringTool: Skipping optional fixer: idioms
RefactoringTool: Skipping optional fixer: set_literal
RefactoringTool: Skipping optional fixer: ws_comma
RefactoringTool: No changes to bin/fail2ban-client
RefactoringTool: No changes to bin/fail2ban-regex
RefactoringTool: No changes to bin/fail2ban-server
RefactoringTool: No changes to bin/fail2ban-testcases
RefactoringTool: No changes to fail2ban/__init__.py
RefactoringTool: No changes to fail2ban/exceptions.py
RefactoringTool: Refactored fail2ban/helpers.py
RefactoringTool: No changes to fail2ban/protocol.py
RefactoringTool: No changes to fail2ban/setup.py
RefactoringTool: No changes to fail2ban/version.py
RefactoringTool: No changes to fail2ban/client/__init__.py
RefactoringTool: Refactored fail2ban/client/actionreader.py
RefactoringTool: No changes to fail2ban/client/beautifier.py
RefactoringTool: Refactored fail2ban/client/configparserinc.py
RefactoringTool: Refactored fail2ban/client/configreader.py
RefactoringTool: No changes to fail2ban/client/configurator.py
RefactoringTool: Refactored fail2ban/client/csocket.py
RefactoringTool: Refactored fail2ban/client/fail2banclient.py
RefactoringTool: No changes to fail2ban/client/fail2bancmdline.py
RefactoringTool: No changes to fail2ban/client/fail2banreader.py
RefactoringTool: Refactored fail2ban/client/fail2banregex.py
RefactoringTool: No changes to fail2ban/client/fail2banserver.py
RefactoringTool: Refactored fail2ban/client/filterreader.py
RefactoringTool: Refactored fail2ban/client/jailreader.py
RefactoringTool: No changes to fail2ban/client/jailsreader.py
RefactoringTool: No changes to fail2ban/server/__init__.py
RefactoringTool: Refactored fail2ban/server/action.py
RefactoringTool: Refactored fail2ban/server/actions.py
RefactoringTool: Refactored fail2ban/server/asyncserver.py
RefactoringTool: Refactored fail2ban/server/banmanager.py
RefactoringTool: Refactored fail2ban/server/database.py
RefactoringTool: No changes to fail2ban/server/datedetector.py
RefactoringTool: No changes to fail2ban/server/datetemplate.py
RefactoringTool: Refactored fail2ban/server/failmanager.py
RefactoringTool: Refactored fail2ban/server/failregex.py
RefactoringTool: Refactored fail2ban/server/filter.py
RefactoringTool: No changes to fail2ban/server/filtergamin.py
RefactoringTool: Refactored fail2ban/server/filterpoll.py
RefactoringTool: Refactored fail2ban/server/filterpyinotify.py
RefactoringTool: Refactored fail2ban/server/filtersystemd.py
RefactoringTool: Refactored fail2ban/server/ipdns.py
RefactoringTool: Refactored fail2ban/server/jail.py
RefactoringTool: No changes to fail2ban/server/jails.py
RefactoringTool: No changes to fail2ban/server/jailthread.py
RefactoringTool: Refactored fail2ban/server/mytime.py
RefactoringTool: No changes to fail2ban/server/observer.py
RefactoringTool: Refactored fail2ban/server/server.py
RefactoringTool: Refactored fail2ban/server/strptime.py
RefactoringTool: Refactored fail2ban/server/ticket.py
RefactoringTool: Refactored fail2ban/server/transmitter.py
RefactoringTool: Refactored fail2ban/server/utils.py
RefactoringTool: No changes to fail2ban/tests/__init__.py
RefactoringTool: No changes to fail2ban/tests/actionstestcase.py
RefactoringTool: Refactored fail2ban/tests/actiontestcase.py
RefactoringTool: Refactored fail2ban/tests/banmanagertestcase.py
RefactoringTool: No changes to fail2ban/tests/clientbeautifiertestcase.py
RefactoringTool: Refactored fail2ban/tests/clientreadertestcase.py
RefactoringTool: Refactored fail2ban/tests/databasetestcase.py
RefactoringTool: Refactored fail2ban/tests/datedetectortestcase.py
RefactoringTool: No changes to fail2ban/tests/dummyjail.py
RefactoringTool: Refactored fail2ban/tests/fail2banclienttestcase.py
RefactoringTool: Refactored fail2ban/tests/fail2banregextestcase.py
RefactoringTool: Refactored fail2ban/tests/failmanagertestcase.py
RefactoringTool: Refactored fail2ban/tests/filtertestcase.py
RefactoringTool: Refactored fail2ban/tests/misctestcase.py
RefactoringTool: Refactored fail2ban/tests/observertestcase.py
RefactoringTool: Refactored fail2ban/tests/samplestestcase.py
RefactoringTool: Refactored fail2ban/tests/servertestcase.py
RefactoringTool: Refactored fail2ban/tests/sockettestcase.py
RefactoringTool: No changes to fail2ban/tests/tickettestcase.py
RefactoringTool: Refactored fail2ban/tests/utils.py
RefactoringTool: No changes to fail2ban/tests/action_d/__init__.py
RefactoringTool: No changes to fail2ban/tests/action_d/test_smtp.py
RefactoringTool: No changes to fail2ban/tests/files/ignorecommand.py
RefactoringTool: No changes to fail2ban/tests/files/action.d/action.py
RefactoringTool: No changes to fail2ban/tests/files/action.d/action_checkainfo.py
RefactoringTool: No changes to fail2ban/tests/files/action.d/action_errors.py
RefactoringTool: No changes to fail2ban/tests/files/action.d/action_modifyainfo.py
RefactoringTool: Refactored fail2ban/tests/files/config/apache-auth/digest.py
RefactoringTool: Files that were modified:
RefactoringTool: bin/fail2ban-client
RefactoringTool: bin/fail2ban-regex
RefactoringTool: bin/fail2ban-server
RefactoringTool: bin/fail2ban-testcases
RefactoringTool: fail2ban/__init__.py
RefactoringTool: fail2ban/exceptions.py
RefactoringTool: fail2ban/helpers.py
RefactoringTool: fail2ban/protocol.py
RefactoringTool: fail2ban/setup.py
RefactoringTool: fail2ban/version.py
RefactoringTool: fail2ban/client/__init__.py
RefactoringTool: fail2ban/client/actionreader.py
RefactoringTool: fail2ban/client/beautifier.py
RefactoringTool: fail2ban/client/configparserinc.py
RefactoringTool: fail2ban/client/configreader.py
RefactoringTool: fail2ban/client/configurator.py
RefactoringTool: fail2ban/client/csocket.py
RefactoringTool: fail2ban/client/fail2banclient.py
RefactoringTool: fail2ban/client/fail2bancmdline.py
RefactoringTool: fail2ban/client/fail2banreader.py
RefactoringTool: fail2ban/client/fail2banregex.py
RefactoringTool: fail2ban/client/fail2banserver.py
RefactoringTool: fail2ban/client/filterreader.py
RefactoringTool: fail2ban/client/jailreader.py
RefactoringTool: fail2ban/client/jailsreader.py
RefactoringTool: fail2ban/server/__init__.py
RefactoringTool: fail2ban/server/action.py
RefactoringTool: fail2ban/server/actions.py
RefactoringTool: fail2ban/server/asyncserver.py
RefactoringTool: fail2ban/server/banmanager.py
RefactoringTool: fail2ban/server/database.py
RefactoringTool: fail2ban/server/datedetector.py
RefactoringTool: fail2ban/server/datetemplate.py
RefactoringTool: fail2ban/server/failmanager.py
RefactoringTool: fail2ban/server/failregex.py
RefactoringTool: fail2ban/server/filter.py
RefactoringTool: fail2ban/server/filtergamin.py
RefactoringTool: fail2ban/server/filterpoll.py
RefactoringTool: fail2ban/server/filterpyinotify.py
RefactoringTool: fail2ban/server/filtersystemd.py
RefactoringTool: fail2ban/server/ipdns.py
RefactoringTool: fail2ban/server/jail.py
RefactoringTool: fail2ban/server/jails.py
RefactoringTool: fail2ban/server/jailthread.py
RefactoringTool: fail2ban/server/mytime.py
RefactoringTool: fail2ban/server/observer.py
RefactoringTool: fail2ban/server/server.py
RefactoringTool: fail2ban/server/strptime.py
RefactoringTool: fail2ban/server/ticket.py
RefactoringTool: fail2ban/server/transmitter.py
RefactoringTool: fail2ban/server/utils.py
RefactoringTool: fail2ban/tests/__init__.py
RefactoringTool: fail2ban/tests/actionstestcase.py
RefactoringTool: fail2ban/tests/actiontestcase.py
RefactoringTool: fail2ban/tests/banmanagertestcase.py
RefactoringTool: fail2ban/tests/clientbeautifiertestcase.py
RefactoringTool: fail2ban/tests/clientreadertestcase.py
RefactoringTool: fail2ban/tests/databasetestcase.py
RefactoringTool: fail2ban/tests/datedetectortestcase.py
RefactoringTool: fail2ban/tests/dummyjail.py
RefactoringTool: fail2ban/tests/fail2banclienttestcase.py
RefactoringTool: fail2ban/tests/fail2banregextestcase.py
RefactoringTool: fail2ban/tests/failmanagertestcase.py
RefactoringTool: fail2ban/tests/filtertestcase.py
RefactoringTool: fail2ban/tests/misctestcase.py
RefactoringTool: fail2ban/tests/observertestcase.py
RefactoringTool: fail2ban/tests/samplestestcase.py
RefactoringTool: fail2ban/tests/servertestcase.py
RefactoringTool: fail2ban/tests/sockettestcase.py
RefactoringTool: fail2ban/tests/tickettestcase.py
RefactoringTool: fail2ban/tests/utils.py
RefactoringTool: fail2ban/tests/action_d/__init__.py
RefactoringTool: fail2ban/tests/action_d/test_smtp.py
RefactoringTool: fail2ban/tests/files/ignorecommand.py
RefactoringTool: fail2ban/tests/files/action.d/action.py
RefactoringTool: fail2ban/tests/files/action.d/action_checkainfo.py
RefactoringTool: fail2ban/tests/files/action.d/action_errors.py
RefactoringTool: fail2ban/tests/files/action.d/action_modifyainfo.py
RefactoringTool: fail2ban/tests/files/config/apache-auth/digest.py
Success!
# bash fail2ban-testcases-all-python3
Testing using /usr/local/bin/python3.9
Fail2ban 1.0.3.dev1 test suite. Python 3.9.15 (main, Oct 15 2022, 00:33:51) [Clang 13.0.0 ]. Please wait...
.............................ss.........................................FF....................................................................s.............................s....................................................................F................................................................FFF............................................................................................................................
.F=== Catch an exception: '\\125-000-001 1;\n' was not found in '%s 1;\n%s 1;\n%s 1;\n%s 1;\n%s 1;\n'
=== Error of server, log: ===
/tmp/f2b-temp9z9pqg_s/blck-failures.log has been modified
Processing line with time:1671495573.0 and ip:125-000-001
[nginx-blck-lst] Found 125-000-001 - 2022-12-20 01:19:33
Total # of detected failures: 1. Current failures from 1 IPs (IP:count): 125-000-001:1
...
Ran 503 tests in 64.270s

FAILED (failures=11, skipped=5)
E: Failed with  /usr/local/bin/python3.9

The failed tests are:

  1. testExecuteTimeout (fail2ban.tests.actiontestcase.CommandActionTest)
  2. testExecuteTimeoutWithNastyChildren (fail2ban.tests.actiontestcase.CommandActionTest)
  3. testIgnoreIPNOK (fail2ban.tests.filtertestcase.IgnoreIP)
  4. testIpToIp (fail2ban.tests.filtertestcase.DNSUtilsNetworkTests)
  5. testIpToName (fail2ban.tests.filtertestcase.DNSUtilsNetworkTests)
  6. testTextToIp (fail2ban.tests.filtertestcase.DNSUtilsNetworkTests)
  7. testKillAfterStart (fail2ban.tests.fail2banclienttestcase.Fail2banServerTest)
  8. testServerActions_NginxBlockMap (fail2ban.tests.fail2banclienttestcase.Fail2banServerTest)
  9. testDirectRE_1 (fail2ban.tests.fail2banregextestcase.Fail2banRegexTest)
  10. testLogTargetSYSLOG (fail2ban.tests.servertestcase.TransmitterLogging)
  11. testSyslogSocketNOK (fail2ban.tests.servertestcase.TransmitterLogging)

Finally, we install it by running:

# python3 -v setup.py install
import _frozen_importlib # frozen
import _imp # builtin
...
creating /usr/local/lib/python3.9/site-packages/fail2ban
copying build/lib/fail2ban/__init__.py -> /usr/local/lib/python3.9/site-packages/fail2ban
copying build/lib/fail2ban/exceptions.py -> /usr/local/lib/python3.9/site-packages/fail2ban
copying build/lib/fail2ban/helpers.py -> /usr/local/lib/python3.9/site-packages/fail2ban
copying build/lib/fail2ban/protocol.py -> /usr/local/lib/python3.9/site-packages/fail2ban
...
byte-compiling /usr/local/lib/python3.9/site-packages/fail2ban/__init__.py to __init__.cpython-39.pyc
byte-compiling /usr/local/lib/python3.9/site-packages/fail2ban/exceptions.py to exceptions.cpython-39.pyc
byte-compiling /usr/local/lib/python3.9/site-packages/fail2ban/helpers.py to helpers.cpython-39.pyc
...
creating /etc/fail2ban
copying config/fail2ban.conf -> /etc/fail2ban
copying config/jail.conf -> /etc/fail2ban
copying config/paths-arch.conf -> /etc/fail2ban
copying config/paths-common.conf -> /etc/fail2ban
...
# cleanup[3] wiping _sha3
# cleanup[3] wiping _blake2
# cleanup[3] wiping _hashlib
...
# destroy _sitebuiltins
# destroy importlib.util
# destroy importlib.abc
...
# destroy select
# destroy _frozen_importlib
# clear sys.audit hooks


root@main:/root/dev/f2b/fail2ban# fail2ban-client -v                                                                                                       
2022-12-20 01:38:02,945 fail2ban.configreader   [33416]: INFO    Loading configs for fail2ban under /etc/fail2ban
2022-12-20 01:38:02,948 fail2ban.configparserinc[33416]: INFO      Loading files: ['/etc/fail2ban/fail2ban.conf']
2022-12-20 01:38:02,950 fail2ban.configparserinc[33416]: INFO      Loading files: ['/etc/fail2ban/fail2ban.conf']
2022-12-20 01:38:02,951 fail2ban                [33416]: INFO    Using socket file /var/run/fail2ban/fail2ban.sock
2022-12-20 01:38:02,951 fail2ban                [33416]: INFO    Using pid file /var/run/fail2ban/fail2ban.pid, [INFO] logging to /var/log/fail2ban.log
Usage: fail2ban-client [OPTIONS] <COMMAND>

Fail2Ban v1.0.3.dev1 reads log file that contains password failure report

It works! ... I thought it was supposed to be the stable version 1.0.2, but anyway!

We now need to modify some defaults and add the jails before its first run.

Initial Configuration

As instructed on the Wiki page Proper fail2ban configuration, we copy the corresponding ".conf" file to ".local", and we only modify the local files. In the configuration directory we find:

# tree -L 1 /etc/fail2ban
/etc/fail2ban
|-- action.d
|-- fail2ban.conf
|-- fail2ban.d
|-- filter.d
|-- jail.conf
|-- jail.d
|-- paths-arch.conf
|-- paths-common.conf
|-- paths-debian.conf
|-- paths-fedora.conf
|-- paths-freebsd.conf
|-- paths-opensuse.conf
`-- paths-osx.conf

We create paths-openbsd.conf from paths-freebsd.conf:

# OpenBSD
[INCLUDES]
before = paths-common.conf
after  = paths-overrides.local
[DEFAULT]
# https://man.openbsd.org/syslog.conf.5
#
syslog_authpriv = /var/log/authlog
syslog_mail = /var/log/maillog
syslog_mail_warn = /var/log/maillog
apache_error_log = /var/www/logs/httpd-error.log
apache_access_log = /var/www/logs/httpd-access.log
nginx_error_log = /var/www/logs/error*.log
nginx_access_log = /var/www/logs/access*.log

The main difference is that on OpenBSD, the web servers are chrooted by default on /var/www, so the log files are all stored at /var/www/logs.

Customising jail.conf

We copy jail.conf to jail.local and change the following lines:

- Line 36:
before = paths-openbsd.conf
- Uncomment lines 49, 53, 61, and 65:
bantime.increment = true
bantime.rndtime = 6m
bantime.factor = 1
bantime.formula = ban.Time * (1<<(ban.Count if ban.Count<20 else 20)) * banFactor
- We add our public IP (111.222.000.111) to ignoreip:
ignoreip = 127.0.0.1/8 ::1 111.222.000.111
- ... and:
findtime  = 60m
logencoding = utf-8
- Most important, the Ban action:
banaction = pf
banaction_allports = pf

Add jail for sshd

Finally, we add a jail for ssh by adding the file /etc/fail2ban/jail.d/sshd.conf:

[sshd]
enabled  = true
maxretry = 2
bantime  = 13m

The name of the jail in braquets coincides with the names of the jails defined in the file jail.conf. For nginx we have: [nginx-http-auth], [nginx-limit-req], [nginx-botsearch], and [nginx-bad-request]. We can create another file for nginx (nginx.conf) with all the jails:

[nginx-http-auth]
enabled  = true

[nginx-limit-req]
enabled  = true

[nginx-botsearch]
enabled  = true

[nginx-bad-request]
enabled  = true

We should now be able to start fail2ban withour errors:

# fail2ban-client -v start
2022-12-20 02:43:06,105 fail2ban.configreader   [79930]: INFO Loading configs for fail2ban under /etc/fail2ban
2022-12-20 02:43:06,108 fail2ban.configparserinc[79930]: INFO Loading files: ['/etc/fail2ban/fail2ban.conf']
2022-12-20 02:43:06,110 fail2ban.configparserinc[79930]: INFO Loading files: ['/etc/fail2ban/fail2ban.conf']
2022-12-20 02:43:06,110 fail2ban                [79930]: INFO Using socket file /var/run/fail2ban/fail2ban.sock
2022-12-20 02:43:06,111 fail2ban                [79930]: INFO Using pid file /var/run/fail2ban/fail2ban.pid, [INFO] logging to /var/log/fail2ban.log
2022-12-20 02:43:06,215 fail2ban.configreader   [79930]: INFO Loading configs for jail under /etc/fail2ban
2022-12-20 02:43:06,217 fail2ban.configparserinc[79930]: INFO Loading files: ['/etc/fail2ban/jail.conf']
2022-12-20 02:43:06,237 fail2ban.configparserinc[79930]: INFO Loading files: ['/etc/fail2ban/paths-debian.conf']
2022-12-20 02:43:06,238 fail2ban.configparserinc[79930]: INFO Loading files: ['/etc/fail2ban/paths-common.conf']
2022-12-20 02:43:06,240 fail2ban.configparserinc[79930]: INFO Loading files: ['/etc/fail2ban/paths-overrides.local']
2022-12-20 02:43:06,243 fail2ban.configparserinc[79930]: INFO Loading files: ['/etc/fail2ban/jail.d/sshd.conf']
2022-12-20 02:43:06,244 fail2ban.configparserinc[79930]: INFO Loading files: ['/etc/fail2ban/jail.local']
2022-12-20 02:43:06,262 fail2ban.configparserinc[79930]: INFO Loading files: ['/etc/fail2ban/paths-openbsd.conf']
2022-12-20 02:43:06,263 fail2ban.configparserinc[79930]: INFO Loading files: ['/etc/fail2ban/paths-common.conf', '/etc/fail2ban/paths-debian.conf', '/etc/fail2ban/jail.conf', '/etc/fail2ban/jail.d/sshd.conf', '/etc/fail2ban/paths-common.conf', '/etc/fail2ban/paths-openbsd.conf', '/etc/fail2ban/jail.local']
2022-12-20 02:43:06,274 fail2ban.configreader   [79930]: INFO Loading configs for action.d/pf under /etc/fail2ban
2022-12-20 02:43:06,274 fail2ban.configparserinc[79930]: INFO Loading files: ['/etc/fail2ban/action.d/pf.conf']
2022-12-20 02:43:06,276 fail2ban.configparserinc[79930]: INFO Loading files: ['/etc/fail2ban/action.d/pf.conf']
2022-12-20 02:43:06,294 fail2ban.configreader   [79930]: INFO Loading configs for filter.d/sshd under /etc/fail2ban
2022-12-20 02:43:06,295 fail2ban.configparserinc[79930]: INFO Loading files: ['/etc/fail2ban/filter.d/sshd.conf']
2022-12-20 02:43:06,298 fail2ban.configparserinc[79930]: INFO Loading files: ['/etc/fail2ban/filter.d/common.conf']
2022-12-20 02:43:06,300 fail2ban.configparserinc[79930]: INFO Loading files: ['/etc/fail2ban/filter.d/common.local']
2022-12-20 02:43:06,300 fail2ban.configparserinc[79930]: INFO Loading files: ['/etc/fail2ban/filter.d/common.conf', '/etc/fail2ban/filter.d/sshd.conf']
2022-12-20 02:43:06,525 fail2ban                [35278]: INFO Using socket file /var/run/fail2ban/fail2ban.sock
2022-12-20 02:43:06,525 fail2ban                [35278]: INFO Using pid file /var/run/fail2ban/fail2ban.pid, [INFO] logging to /var/log/fail2ban.log
2022-12-20 02:43:06,607 fail2ban.server         [35278]: INFO Starting in daemon mode
Server ready

PF configuration

The last piece of the puzzle is PF. We just need to add the following to /etc/pf.conf:

anchor "f2b/*"

We can check the banned IPs by checking the log file /var/log/fail2ban.log or by running:

# fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed:    1
|  |- Total failed:    773
|  `- File list:    /var/log/authlog
`- Actions
   |- Currently banned:    5
   |- Total banned:    329
   `- Banned IP list:    109.107.166.160 195.226.194.242 162.243.165.205 23.94.43.69 42.96.40.182


HTH


Sunday 15 December 2019

Spinrite 6.0 on Virtualbox (Linux)



I have found a significant difference in performance depending how the VM is configured in VirtualBox (IDE vs SATA). This is the process I follow to scan hard disks connected via USB adaptors on a Virtual Machine:

Create the VM
  1. Type: Other, Version: DOS
  2. System: Disable Floppy; Memory: 128MB
  3. Storage
    1. Remove the IDE Storage Controller
    2. Add a SATA Controller, enable Host I/O Cache
    3. Add an Optical Drive and choose the Spinrite.iso
    4. Insert the USB drive
    5. As root type dmesg on the command line and identify the device, for example /dev/sdb
    6. chmod o+rw /dev/sdb
    7. As the user running VirtualBox run:
      VBoxManage internalcommands createrawvmdk -filename VirtualBox/sdb.vmdk -rawdisk /dev/sdb
    8. Add a Hard Disk to the SATA Controller > existing disk: sdb.vmdk
  4. Sound: Disabled.
  5. Network: Disable the Network adapter.
VirtualBox Storage configuration


Using the default IDE storage controller slows down the scan by a factor of 10 (approx)

The lack of support for GPT partition tables of the current version of Spinrite (6.0) is a major drawback. I still use it for checking hard disks and data recovery with my old drives, or with new ones, as long as I initiate them with a MBR partition table.

Friday 17 May 2019

Avoid losing the OpenVPN's CA data on EdgeOS

After updating the firmware of an EdgeRouter 8 to v2.0.1, all CA data stored initially at /usr/lib/ssl/misc/demoCA was lost:

- cacert.pem
- careq.pem
d certs
d crl
- crlnumber
- index.txt
- index.txt.attr
- index.txt.attr.old
- index.txt.old
d newcerts
d private
  - cacert.key
- serial
- serial.old

Luckily, I had the CA's certificate and private key stored at /config/auth, but not the rest of the files. In order not to lose these files next time I upgrade the firmware, I have moved the newly created demoCA directory to /config/auth, and updated the configuration file /etc/ssl/openssl.cnf. Where it says:

dir      = ./demoCA

I have changed it to: 

dir      = /config/auth/demoCA

Monday 17 December 2018

Unable to compile VirtualBox Guest Additions on CentOS kernel version 3.10.0-957

The Guest Additions for VirtualBox fail to be built on the kernel released on November 12th 2018, version 3.10.0-957 for CentOS 7.

After upgrading the kernel from 3.10.0-862 the compilation of the Guest Additions' modules generates the following errors:

Building the graphics driver module.
Error building the module.  Build output follows.
make V=1 CONFIG_MODULE_SIG= -C /lib/modules/3.10.0-957.1.3.el7.x86_64/build SUBDIRS=/tmp/vbox.0 SRCROOT=/tmp/vbox.0 -j2 modules
make[1]: warning: -jN forced in submake: disabling jobserver mode.
test -e include/generated/autoconf.h -a -e include/config/auto.conf || (                \
echo >&2;                                                       \
echo >&2 "  ERROR: Kernel configuration is invalid.";           \
echo >&2 "         include/generated/autoconf.h or include/config/auto.conf are missing.";\
echo >&2 "         Run 'make oldconfig && make prepare' on kernel src to fix it.";      \
echo >&2 ;                                                      \
/bin/false)
mkdir -p /tmp/vbox.0/.tmp_versions ; rm -f /tmp/vbox.0/.tmp_versions/*
...
/tmp/vbox.0/vbox_mode.c: In function ‘vbox_best_single_encoder’:
/tmp/vbox.0/vbox_mode.c:358:3: warning: passing argument 2 of ‘drm_encoder_find’ makes pointer from integer without a cast [enabled by default]
   return drm_encoder_find(connector->dev, enc_id);
   ^
In file included from /tmp/vbox.0/vbox_drv.h:89:0,
                 from /tmp/vbox.0/vbox_mode.c:35:
include/drm/drm_encoder.h:221:35: note: expected ‘struct drm_file *’ but argument is of type ‘int’
 static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev,
                                   ^
/tmp/vbox.0/vbox_mode.c:358:3: error: too few arguments to function ‘drm_encoder_find’
   return drm_encoder_find(connector->dev, enc_id);
   ^
In file included from /tmp/vbox.0/vbox_drv.h:89:0,
                 from /tmp/vbox.0/vbox_mode.c:35:
include/drm/drm_encoder.h:221:35: note: declared here
 static inline struct drm_encoder *drm_encoder_find(struct drm_device *dev,
                                   ^
make[2]: *** [/tmp/vbox.0/vbox_mode.o] Error 1
make[2]: *** Waiting for unfinished jobs....
/tmp/vbox.0/vbox_ttm.c: In function ‘vbox_ttm_tt_create’:
/tmp/vbox.0/vbox_ttm.c:225:2: warning: passing argument 2 of ‘ttm_tt_init’ from incompatible pointer type [enabled by default]
  if (ttm_tt_init(tt, bdev, size, page_flags, dummy_read_page)) {
  ^
In file included from include/drm/ttm/ttm_bo_driver.h:45:0,
                 from /tmp/vbox.0/vbox_drv.h:93,
                 from /tmp/vbox.0/vbox_ttm.c:31:
include/drm/ttm/ttm_tt.h:161:5: note: expected ‘struct ttm_buffer_object *’ but argument is of type ‘struct ttm_bo_device *’
 int ttm_tt_init(struct ttm_tt *ttm, struct ttm_buffer_object *bo,
     ^
/tmp/vbox.0/vbox_ttm.c:225:2: error: too many arguments to function ‘ttm_tt_init’
  if (ttm_tt_init(tt, bdev, size, page_flags, dummy_read_page)) {
  ^
In file included from include/drm/ttm/ttm_bo_driver.h:45:0,
                 from /tmp/vbox.0/vbox_drv.h:93,
                 from /tmp/vbox.0/vbox_ttm.c:31:
include/drm/ttm/ttm_tt.h:161:5: note: declared here
 int ttm_tt_init(struct ttm_tt *ttm, struct ttm_buffer_object *bo,
     ^
/tmp/vbox.0/vbox_ttm.c: In function ‘vbox_ttm_tt_populate’:
/tmp/vbox.0/vbox_ttm.c:240:2: error: too few arguments to function ‘ttm_pool_populate’
  return ttm_pool_populate(ttm);
  ^
In file included from /tmp/vbox.0/vbox_ttm.c:32:0:
include/drm/ttm/ttm_page_alloc.h:50:5: note: declared here
 int ttm_pool_populate(struct ttm_tt *ttm, struct ttm_operation_ctx *ctx);
     ^
/tmp/vbox.0/vbox_ttm.c: At top level:
/tmp/vbox.0/vbox_ttm.c:257:2: warning: initialization from incompatible pointer type [enabled by default]
  .ttm_tt_create = vbox_ttm_tt_create,
  ^
/tmp/vbox.0/vbox_ttm.c:257:2: warning: (near initialization for ‘vbox_bo_driver.ttm_tt_create’) [enabled by default]
/tmp/vbox.0/vbox_ttm.c:259:2: warning: initialization from incompatible pointer type [enabled by default]
  .ttm_tt_populate = vbox_ttm_tt_populate,
  ^
/tmp/vbox.0/vbox_ttm.c:259:2: warning: (near initialization for ‘vbox_bo_driver.ttm_tt_populate’) [enabled by default]
/tmp/vbox.0/vbox_ttm.c:272:16: error: ‘ttm_bo_default_io_mem_pfn’ undeclared here (not in a function)
  .io_mem_pfn = ttm_bo_default_io_mem_pfn,
                ^
/tmp/vbox.0/vbox_ttm.c: In function ‘vbox_bo_create’:
/tmp/vbox.0/vbox_ttm.c:417:6: warning: passing argument 8 of ‘ttm_bo_init’ makes integer from pointer without a cast [enabled by default]
      NULL, vbox_bo_ttm_destroy);
      ^
In file included from /tmp/vbox.0/vbox_drv.h:92:0,
                 from /tmp/vbox.0/vbox_ttm.c:31:
include/drm/ttm/ttm_bo_api.h:544:5: note: expected ‘size_t’ but argument is of type ‘void *’
 int ttm_bo_init(struct ttm_bo_device *bdev, struct ttm_buffer_object *bo,
     ^
/tmp/vbox.0/vbox_ttm.c:417:6: warning: passing argument 9 of ‘ttm_bo_init’ makes pointer from integer without a cast [enabled by default]
      NULL, vbox_bo_ttm_destroy);
      ^
In file included from /tmp/vbox.0/vbox_drv.h:92:0,
                 from /tmp/vbox.0/vbox_ttm.c:31:
include/drm/ttm/ttm_bo_api.h:544:5: note: expected ‘struct sg_table *’ but argument is of type ‘size_t’
 int ttm_bo_init(struct ttm_bo_device *bdev, struct ttm_buffer_object *bo,
     ^
/tmp/vbox.0/vbox_ttm.c:417:6: error: too many arguments to function ‘ttm_bo_init’
      NULL, vbox_bo_ttm_destroy);
      ^
In file included from /tmp/vbox.0/vbox_drv.h:92:0,
                 from /tmp/vbox.0/vbox_ttm.c:31:
include/drm/ttm/ttm_bo_api.h:544:5: note: declared here
 int ttm_bo_init(struct ttm_bo_device *bdev, struct ttm_buffer_object *bo,
     ^
/tmp/vbox.0/vbox_ttm.c: In function ‘vbox_bo_pin’:
/tmp/vbox.0/vbox_ttm.c:452:2: error: too many arguments to function ‘ttm_bo_validate’
  ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false);
  ^
In file included from /tmp/vbox.0/vbox_drv.h:92:0,
                 from /tmp/vbox.0/vbox_ttm.c:31:
include/drm/ttm/ttm_bo_api.h:344:5: note: declared here
 int ttm_bo_validate(struct ttm_buffer_object *bo,
     ^
/tmp/vbox.0/vbox_ttm.c: In function ‘vbox_bo_unpin’:
/tmp/vbox.0/vbox_ttm.c:486:2: error: too many arguments to function ‘ttm_bo_validate’
  ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false);
  ^
In file included from /tmp/vbox.0/vbox_drv.h:92:0,
                 from /tmp/vbox.0/vbox_ttm.c:31:
include/drm/ttm/ttm_bo_api.h:344:5: note: declared here
 int ttm_bo_validate(struct ttm_buffer_object *bo,
     ^
/tmp/vbox.0/vbox_ttm.c: In function ‘vbox_bo_push_sysram’:
/tmp/vbox.0/vbox_ttm.c:525:2: error: too many arguments to function ‘ttm_bo_validate’
  ret = ttm_bo_validate(&bo->bo, &bo->placement, false, false);
  ^
In file included from /tmp/vbox.0/vbox_drv.h:92:0,
                 from /tmp/vbox.0/vbox_ttm.c:31:
include/drm/ttm/ttm_bo_api.h:344:5: note: declared here
 int ttm_bo_validate(struct ttm_buffer_object *bo,
     ^
make[2]: *** [/tmp/vbox.0/vbox_ttm.o] Error 1
make[1]: *** [_module_/tmp/vbox.0] Error 2
make: *** [vboxvideo] Error 2

I have also attempted to use the beta version 5.2.23, but the Windows device drivers for the VirtualBox devices would not load because of a problem with the drivers' signatures from Oracle.



The only solution I have found so far has been to go back to using kernel version 3.10.0-862.

Wednesday 4 May 2016

Importing Bookmarks to Chrome from another Chrome installation

If you need to import your bookmarks to a new installation of Chrome, unless you log into your Chrome account, I found the task to be not so easy to find. You may need this when you switch to a new computer.

Version 50.0... on Windows 7 has 2 options when you try to import Bookmarks from the Menu Bookmarks > Import Bookmarks and configuration...:

  1. Microsoft Internet Explorer
  2. HTML Bookmarks file
The first option is quite useless, unless what you want to import are the Bookmarks and Settings from the Internet Explorer installed for the same user account as you logged in. I needed to import them from a disk from another computer, so this option is a no go.

The second option appears to be more general, but useless for my case: Chrome to Chrome.

So, the bookmarks file for Chrome on Windows 7 is installed in the file C:/Users/Your-Username/AppData/Local/Google/Chrome/User Data/Default/Bookmarks. You only need to

  1. Close Chrome.
  2. Replace your current Bookmarks file with the old one
  3. Start Chrome
The current Bookmarks are replaced with the old ones.

Saturday 23 April 2016

Debugging module installation on Drupal 7 with NetBeans

After following Configuring NetBeans, a very informative post on Drupal, I could still not debug my module on NetBeans 8.1. My main problem was that the breakpoints set on any of my module's files appeared as broken. In order to fix this, I needed to let NetBeans know which server request calls the module's code.

The Server request


Using Chrome's "Inspect" feature on the /admin/modules page after enabling my module and submitting the form, I found out that the module installation was being initiated by a POST request to "http://.../admin/modules/list/confirm".

I had created an apache virtual site to host it. On NetBeans, I included the whole Drupal 7 web tree as the project source (var/www/drupal7), and modified the project's Run Configuration accordingly (right click on the project's name > Properties):

NetBeans Project Properties - Run Configuration
Project Properties - Run Configuration
On the Advanced... settings window, I added the following Path Mapping:
  • Server Path: http://mylocalserver.local/admin/modules/list/confirm
  • Project Path: click on the ... and browse to the directory where your module is installed: /var/www/drupal7/sites/all/modules/my_module

Project Properties - Run - Advanced Web Configuration
Project Properties - Run Configuration - Advanced...


After this, the break points set on the files under .../my_module appeared and worked just fine.

Friday 25 March 2016

IIS Installation... no static content by default

I recently discovered that my initial installation of IIS 7.5 on Windows 7 professional didn't include basic features like serving static content... surprise!

So I reinstalled IIS following this guide on iis.net. On point number 7 of that page, it describes how to enable "Common Http Features" that are not enabled by default like: Directory browsing, or Static Content. This is the part I had missed before, I couldn't imagine that the default installation didn't include these basic features.