Solaris: script to cre­ate com­mands to set­up LDOMs based upon out­put from “ldm ls”

Prob­lem

You have a LDOM which you want to clone to some­where else and all you have to per­form that is the ldm com­mand on the tar­get system.

Solu­tion

Down­load the AWK script below. Use the out­put of “ldm ls ‑l ‑p <ldom>” as the input of this AWK script. The out­put will be a list of com­mands to re-create the con­fig for VDS, VDISK, VSW and NETWORK.

I wrote this in 2013, so changes to the out­put of “ldm ls” since then are not account­ed for.

Win­dows: remove one item from filesys­tem ACL

Pow­er­Shell snip­pets to remove a group/user from a filesys­tem ACL in Win­dows (and com­pare how to do it in Linux/FreeBSD/Solaris).

Prob­lem

There may be a fold­er (with bro­ken inher­i­tance) with files / direc­to­ries where you want to make sure that there is no spe­cif­ic group / item included.

Solu­tion

Here are some Pow­er­Shell snip­pets to solve this.

Pop­u­late $fold­ers with all direc­to­ries in the cur­rent directory:

$folders =  get-childitem . -directory

To test with one folder:

$folders = "X:\path\to\folder"

Pow­er­Shell to list fold­ers with BUILTIN\Users in the ACL (to see which item will be affected):

foreach ($dir in $folders) { $value = get-acl $dir | Select-object -ExpandProperty Access | where { $_.IdentityReference -eq "BUILTIN\Users"} | Select -Expand IdentityReference; if ($value) {echo $dir} }

Print ACL of before and “to be” after removal (but not remov­ing anything):

foreach ($item in $folders) { $value = get-acl $item | Select-object -ExpandProperty Access | where { $_.IdentityReference -eq "BUILTIN\Users"} | Select -Expand IdentityReference; if ($value) {echo $item; $ACL = (get-item $item).getAccessControl('Access'); $ACL.SetAccessRuleProtection($true, $true); echo $ACL |Select-object -ExpandProperty Access; $ACL = (get-item $item).getAccessControl('Access'); $ACL.Access | where {$_.IdentityReference -eq "BUILTIN\Users"} |%{$acl.RemoveAccessRule($_)}; echo $ACL |Select-object -ExpandProperty Access } }

Set the ACL (dis­able inher­i­tance (con­vert cur­rent set­tings to explic­it ACL) and remove BUILTIN\Users):

foreach ($item in $folders) { $value = get-acl $item | Select-object -ExpandProperty Access | where { $_.IdentityReference -eq "BUILTIN\Users"} | Select -Expand IdentityReference; if ($value) {echo $item; $ACL = (get-item $item).getAccessControl('Access'); $ACL.SetAccessRuleProtection($true, $true); Set-Acl -Path $item -AclObject $ACL; $ACL = (get-item $item).getAccessControl('Access'); $ACL.Access | where {$_.IdentityReference -eq "BUILTIN\Users"} |%{$acl.RemoveAccessRule($_)}; Set-Acl -Path $item -AclObject $ACL } }

How would this be solved in Solaris?

setfacl -d <entry> *

How would this be solved in FreeBSD/Linux?

setfacl -x <entry> *

Self-signed cer­tifi­cates and LDAPS (OpenL­DAP) in PHP (or python)

This is not about how to gen­er­ate a self-signed cer­tifi­cate, this is about how to con­fig­ure an ldap client to con­nect secure­ly to a ldap serv­er which has a self-signed certificate.

Recent­ly I was search­ing a lot how to make this kind of set­up work, but it seems nobody is using the key­words of the head­line in their HOW­TOs, or every­one is not real­ly set­ting up a real­ly secure con­nec­tion with self-signed cer­tifi­cates. As such here my try to doc­u­ment this for those which are inter­est­ed in a secure setup.

How OpenL­DAP is check­ing the cer­tifi­cates normally

OpenL­DAP is using the cer­tifi­cate store which is con­fig­ured for OpenSSL. So any cer­tifi­cate which is signed by one of the CAs in the OpenSSL cert-ctore are trusted.

Secure set­up

Most of the time you do not expose an LDAP serv­er to the out­side where a cer­tifi­cate from one of the trusted-by-default CAs is need­ed. A cer­tifi­cate from your inter­nal CA is enough, and in some cas­es a self-signed cer­tifi­cate is suf­fi­cient too.

An easy solu­tion could be to add either the root-certificate of your CA or the self-signed cer­tifi­cate into the trust-store of OpenSSL (not every OS / dis­tri­b­u­tion has this in the same loca­tion, you have to check where this is for your OS, for FreeB­SD 13+ this is /usr/local/etc/ssl/certs/, see also certctl(8) there). But this would mean you trust the cer­ti­ti­fa­cate which you put there addi­tion­al­ly to the default cer­tifi­cates (mod­u­lo any black­list­ing you made your­self). The­o­ret­i­cal­ly this means any­one who is able to get hold of a cer­tifi­cate from a public-CA for your LDAP serv­er, could per­form a man-in-the-middle attack (you need to con­sid­er your­self how fea­si­ble this is in your infra­struc­ture set­up and how like­ly this is to happen).

More secure operation

Let’s say you run a ser­vice which needs to be able to make TLS ses­sions to sys­tems which use cer­tifi­cates from pub­lic CAs and you want to make sure a con­nec­tion to the LDAP back­end can not use cer­tifi­cates from pub­lic CAs.

To tight­en the set­up in this case, you need to spec­i­fy that the client which uses OpenLDAP-client libraries is using a dif­fer­ent trust-store for the cer­tifcate validation.

For the openl­dap client util­i­ties there is a glob­al con­fig file for this (on FreeB­SD this is /usr/local/etc/openldap/ldap.conf). For oth­er tools, like PHP, this needs to be done in the per-user con­fig file ~/.ldaprc. Both file have the same syntax.

With php-ldap you nor­mal­ly run the ser­vice either in php-fpm or in an apache-php-module. In both cas­es the process which runs is con­fig­ured to run as a non-root user which may or may not have a home direc­to­ry (in FreeB­SD the www user which is typ­i­cal­ly used for that has no home directory).

HOWTO

  1. cre­ate a home directory
  2. cre­ate a sep­a­rate trust-store for LDAP
  3. con­fig­ure php-ldap / py-ldap to make use of the sep­a­rate trust-store

Step 1 – cre­ate a home directory

Chose a place which is suit­able, and cre­ate a direc­to­ry there. It does­n’t need to be in /home, it can be any­where. The impor­tant part is, that it is read­able by the user which runs the appli­ca­tion which is using php-ldap. It does not need to be writable by this user. In there you need to cre­ate the .ldaprc file (again, needs only be read­able by the user) with the con­tent from step 3.

Step 2 – cre­ate a sep­a­rate trust-store for LDAP

In FreeB­SD the glob­al ldap con­fig is in /usr/local/etc/openldap/ldap.conf. The­o­ret­i­cal­ly you can put the trust-store for LDAP in any place wou want. In my set­up I con­sid­er it to belong into /usr/local/etc/openldap/ssl/. So make a direc­to­ry – like /usr/local/etc/openldap/ssl – for the trust-store, and copy the cer­tifi­cate of the LDAP serv­er there.

Atten­tion! Only the pub­lic cer­tifi­cate, not the pri­vate key! If you only have one file on the serv­er for this, it is the com­bined key+certificate (if you don’t know or are able to deduct by look­ing into the file how to get rid of the key… there is a lot of info out there in the WWW which explains it). The direc­to­ry and the cer­tifi­cate need to be acces­si­ble (read for the file, exe­cute for the direc­to­ry) by any user which shall make use of this. It does not hurt to have it acces­si­ble by every­one (you made sure there is not the private-key from the serv­er, right?).

Step 3 – con­fig­ure php-ldap / py-ldap to make use of the sep­a­rate trust-store

If you use php-fpm, you need to con­fig­ure a home direc­to­ry in the FPM pool con­fig­ure­ation sec­tion. As already said above, it does not need to be inside /home, but it dpends upon your needs. Here in this exam­ple let me use /home. The FPM con­fig line to add is then some­thing like:
env[HOME] = /home/php-fpm
You could achieve the same via chang­ing the home direc­to­ry in the pass­word data­base, but this would have an effect on all process­es run with this user, where­as here it is just for the php-fpm process­es (and childs).

If you use apache instead of php-fpm, you need to con­fig­ure some­thing sim­i­lar for the cor­re­spond­ing vir­tu­al host:
SetEnv HOME /home/php-fpm

With this you can now con­fig­ure /home/php-fpm/.ldaprc to point to the LDAP trust-store:
TLS_CACERT /usr/local/etc/openldap/ssl/ldap_server_cert.pem
TLS_CACERTDIR /usr/local/etc/openldap/ssl

If you use some python based appli­ca­tion, you have to do some­thing sim­i­lar… if all else fails, it needs to be via a real home direc­to­ry in the pass­word database.

If you want to use the ldap client tools with any user, you need to add those lines to the /usr/local/etc/openldap/ldap.conf file too (there you can also set the default BASE – e.g. “BASE dc=example,dc=com” – and URI – e.g. “URI ldaps://ldap.example.com:639″).

After restart­ing php-fpm or apache, you should now be able to make real­ly secure con­nec­tions to the ldap server.

Some impor­tant things

  • Every time you change the cer­tifi­cate of the LDAP serv­er, you need to update the cer­ti­facte in the clients.
  • There are two TLS modes for the LDAP serv­er, one is “ldaps”, and one is “ldap+starttls”. If you have your LDAP serv­er run­ning in ldaps-mode (typ­i­cal­ly on port 639), you do not need to spec­i­fy in your php-ldap using appli­ca­tion to enable TLS (which is doing a start­tls after con­nect­ing… typ­i­cal­ly on port 389), but you need to spec­i­fy “ldaps://servername:639” (assum­ing it runs on port 639) instead of just “server­name” at the place in your appli­ca­tion where you are told to enter the serv­er name. For py-ldap I have checked just one appli­ca­tion (net­da­ta), and there TLS needs to be enabled, and the serv­er name has to be with­out “ldaps://” as net­da­ta is pre­fix­ing the “ldaps://” itself if tls is enabled.
  • Some places in the inter­net are telling to add “TLS_REQCERT nev­er” into ldap.conf / .ldaprc. Tech­ni­cal­ly this is not need­ed. Depend­ing on your point of view this can either be good or bad (spec­i­fy­ing it saves some CPU cycles on the serv­er and the client, and some trans­fer time over the net­work – not spec­i­fy­ing it allows to val­i­date the cer­tifi­cat­ed received to be com­pared to the cer­tifcate being avail­able local­ly, but I do not know if OpenL­DAP is doing this, nor did I spend some time to eval­u­ate if this improves secu­ri­ty (if the impor­tant parts of the cer­tifi­cate are out-of-sync, the con­nec­tion will fail)).

Fight­ing the Coro­n­avirus with FreeB­SD (Folding@Home)

Pho­to by Fusion Med­ical Ani­ma­tion on Unsplash

Here is a quick HOWTO for those which want to pro­vide some FreeB­SD based com­pute resources to help find­ing vac­cines. I have not made a port out of this and do not know yet if I get the time to make one. If some­one wants to make a port, go ahead, do not wait for me.

UPDATE 2020-03-22: 0mp@ made a port out of this, it is in “biology/linux-foldingathome”.

  • Down­load the lin­ux RPM of the Folding@Home client (this cov­ers fah­client only).
  • Enable the lin­ux­u­la­tor (ker­nel moduls and linux_base (first part of chap­ter 10.2) is enough).
  • Make sure linprocfs/linsysfs are mount­ed in /compat/linux/{proc|sys}.
  • cd /compat/linux
  • tar -xf /path/to/fahclient....rpm
  • add the “fah­client” user (give it a real home directory)
  • make sure there is no /compat/linux/dev or alter­na­tive­ly mount devfs there
  • mkdir /compat/linux/etc/fahclient
  • cp /compat/linux/usr/share/doc/fahclient/sample-config.xml /compat/linux/etc/fahclient/config.xml
  • chown -R fahclient /compat/linux/etc/fahclient
  • edit /compat/linux/fahclient/config.xml: mod­i­fy user (manda­to­ry) / team (option­al: FreeB­SD team is 11743) / passkey (option­al) as appro­pri­ate (if you want to con­trol the client remote­ly, you need to mod­i­fy some more parts, but some­how the client “los­es” a filedescrip­tor and stops work­ing as it should if you do that on FreeBSD)
  • If you have the home direc­to­ries of the users as no-exec (e.g. seper­ate ZFS datasets with exec=off): make sure the home direc­to­ry of the fah­client user has exec per­mis­sions enabled
  • cd ~fahclient (impor­tant! it tries to write to the cur­rent work direc­to­ry when you start it)
  • Start it: /usr/sbin/daemon /compat/linux/usr/bin/FAHClient /compat/linux/etc/fahclient/config.xml --run-as fahclient --pid-file=/var/run/fahclient.pid >/dev/null 2>&1

Per default it will now pick up some SARS-CoV‑2 (COVID-19) relat­ed fold­ing tasks. There are some more con­fig options (e.g. how much of the sys­tem resources are used). Please refer to the offi­cial Folding@Home site for more infor­ma­tion about that. Be also aware that there is a big rise in com­pute resources donat­ed to Folding@Home, so the pool of avail­able work units may be emp­ty from time to time, but they are work­ing on adding more work units. Be patient.

VMware 6.5 and 6.7 update fail­ure – rea­son and fix

Prob­lem

If you want to update an ESXi host (or you have upgrad­ed the VMware vSphere appli­ance and try to enable HA on some hosts), some­times it may be the case that it fails (most like­ly when you down­load the update either from VMware via esx­cli com­mand and a https source, or local down­load from the vCen­ter – instead of hav­ing the update on a data­s­tore and point­ing esx­cli to the data­s­tore). If you inves­ti­gate this (in the case of fail­ure to enable HA you may not have a look at esxupdate.log, but if you just updat­ed you vCen­ter appli­ance and the hosts are still on the old ver­sion, just go there and have a look), you may stum­ble on some VMware knowl­edge base arti­cle which tells that this may be a disk space issue on the ESXi host. If you then have a look at the host, you see plen­ty of free space.

Rea­son

You can not see this issue after it has failed, it is only observ­able dur­ing the update process. The rea­son for this is, that the update process is cre­at­ing a ramdisk where it tries to store the update tem­po­rary (at least if the hyper­vi­sor is not installed on some­thing which is detect­ed as a real disk – if you have it installed on a SD card which is detect­ed by the ESXi ker­nel on a USB con­nec­tion, then it is not a real disk in this case; the same is true if it is installed on a SSD behind an USB con­nec­tion, I haven’t found a way to convince/force the installer or the hyper­vi­sor after the instal­la­tion to assume it is a SSD or at least a real disk were it does not need to care about wear-leveling like on a SD card, feel free to add a com­ment to point me to a how­to). This ramdisk is then too small and the update fails.

Solu­tion

Put the update on a data­s­tore and run the update via the esx­cli com­mand. If you use the remote source fea­ture of esx­cli, you will find the down­load URL in esxupdate.log. In case the update comes from the vCen­ter, you can at least find the VIP name in the esxupdate.log and you can use the “find” com­mand to search it in the vCen­ter shell and then scp it to a (shared) data­s­tore on a/the host.