You may need to update your OpenLDAP SSL certificate, as well as the CA certificate and signing key on a regular basis. I ran into an issue that was ultimately resolved by doing that.
Connections to an OpenLDAP server I administer stopped working with this error:
The server itself was up and the relevant ports were accessible. In fact, unencrypted LDAP continued to work while LDAPS saw the error above.
I restarted slapd with -d 255 flag (-d 8 is sufficient for this error) and started seeing this error:
1
TLS:error:could notinitialize moznss security context-error-5925:The one-time functionwas previously called andfailed.Its error code isno longer available TLS:can'tcreate ssl handle.
At the start of the log, I saw several related errors including this one:
1
...isnotvalid-error-8181:Peer'sCertificate has expired..
Ultimately this meant that I had to replace not just my certificate but also the CA certificate and the signing key in OpenLDAP’s moznss database. I believe my CA’s certificate had to be replaced because of the SHA1 retirement last year.
The steps I had to follow were surprisingly involved and undocumented:
Upload the new certificates to /etc/openldap/ssl
cd /etc/openldap/certs
List the existing certificates in the database:
1
certutil-L-d.
Remove the existing certs:
1
2
3
certutil-D-d.-n"OpenLDAP Server"
certutil-D-d.-n"My CA Certificate"
Load the new OpenLDAP SSL certificate and CA certificate:
I am pretty excited about the release of git 2.9. It brings several new features that make reviewing changes easier and more sensible. It has better change grouping, and it can highlight individual changed words. Everyone should set these configuration options to enable better git diffs.
Upgrade your git
Before you can enable the new settings, you have to upgrade your git installation.
If you already have git installed through homebrew, you can upgrade it as follows:
Shell
1
brew update&&brew upgrade
If you do not have git installed through homebrew, you’ll want to override your ancient Mac git by installing it as follows:
Shell
1
brew install git
Enable better git diffs
Once you have upgraded your git, you can put the new configuration in place.
The first major change is an improvement to how git groups changes in a diff. When you add a new block of code, it’s now likelier to see the whole block as a change rather than misinterpreting it as an insertion splitting an existing block into two.
BeforeAfter
The second change is the addition of more places for you to hook in the diff-highlight utility.
diff-highlight post-processes your diffs to add more highlighting to the specific changes between two lines when you just change a few words in a line.
You can enable all of these by running the following commands in your terminal:
I use the bash command line on my Mac a lot. I typically have multiple tabs with multiple terminal panes open in iTerm2, often with multiple ssh sessions running. By default, the last terminal session to close trashes the bash history of all the other sessions. Is it possible to configure the terminal to preserve bash history?
Open up your ~/.bash_profile configuration file in an editor of your choice such as nano. Once you have it open, add these lines at the end:
Shell
1
2
3
4
5
6
7
8
9
10
11
12
13
# Maximum number of history lines in memory
export HISTSIZE=50000
# Maximum number of history lines on disk
export HISTFILESIZE=50000
# Ignore duplicate lines
export HISTCONTROL=ignoredups:erasedups
# When the shell exits, append to the history file
# instead of overwriting it
shopt-shistappend
# After each command, append to the history file
# and reread it
export PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"
Save the file an exit. In order for your configuration change to take effect, you will need to reload the configuration in all your open terminal sessions:
Shell
1
source~/.bash_profile
This configuration change has to be done per user per machine.
Backup your bash configuration
I use mackup together with Dropbox to keep my bash and other command line configuration files backed up. This makes it easy to transfer your command line configuration to a new primary machine.
iTerm2
iTerm2 is my terminal of choice on the Mac. It has great tab and pane management accessible via both keyboard and mouse, and some subtle quality of life features.
For example, if you ssh somewhere, it sets the tab title to the hostname of the remote machine, or the name of the local directory.
Alternatives
One drastic alternative would be to migrate from Bash to an alternate shell like Fish or, in the future, the Next Generation Shell (NGS).
The project I’m working on right now involve not just Dockerized Rails microservices, Meteor JS, and a data set measured in tens of terabytes, but also a big Bash code base.
Bash is a language that makes it easy to shoot yourself in the foot. I have some thoughts on how to write robust, modular, loosely coupled, unit tested Bash that go beyond Bash strict mode and shellcheck. However, let’s save those for later.
Here’s a useful shell command for today: watch
watch will run a command for you every few seconds and output the results on a clean screen. If you combine it with a split-screen or split-pane tool, you can quickly create a mini-dashboard.
For example, watch -n15 df -h will print your free disk space every 15 seconds:
1
2
3
4
5
6
7
Every15.0s:df-h       Tue Apr1413:43:252015
Filesystem           Size Used Avail Use%Mounted on
/dev/sda3Â Â Â Â Â Â Â Â Â Â Â Â 1.8TÂ 691GÂ 1.1TÂ 40%/
tmpfs                253G  12K 253G  1%/dev/shm
/dev/sda1Â Â Â Â Â Â Â Â Â Â Â Â 248MÂ Â 58MÂ 178MÂ 25%/boot
/dev/sdb1Â Â Â Â Â Â Â Â Â Â Â Â Â 30TÂ Â 12TÂ Â 18TÂ 41%/my_disk
By way of another example, watch -n60 db2 list utilities show detail will check on the status of your DB2 load and other operations every 60 seconds.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Every60.0s:db2 list utilities show detail           Mon Apr1312:06:242015
IDÂ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â =4
Type                            =LOAD
Database Name                   =MY_DB
Member Number                   =0
Description                     =[LOADID:1177.2015-04-13-15.58.12.282010.0(20;15)]
[*LOCAL.MY_USER.150413204511]OFFLINE LOAD DEL
AUTOMATIC INDEXING INSERT NON-RECOVERABLE MY_SCHEMAÂ Â Â .MY_TABLE
Start Time                      =04/13/201515:58:12.298788
State                           =Executing
Invocation Type                 =User
Progress Monitoring:
  Phase Number                 =1
     Description               =SETUP
     Total Work                =0bytes
     Completed Work            =0bytes
     Start Time                =04/13/201515:58:12.298799
  Phase Number[Current]       =2
     Description               =LOAD
     Total Work                =4105362974rows
     Completed Work            =1069904365rows
     Start Time                =04/13/201515:58:15.821695
  Phase Number                 =3
     Description               =BUILD
     Total Work                =2indexes
     Completed Work            =0indexes
     Start Time                =NotStarted
Mac OS X does not include watch by default. Assuming you have Homebrew, the following will install watch for you:
An .so is a Linux library, equivalent to a .dll on Windows or a .dylib on Mac. Note that there are two different libraries mentioned. ibm_db.so is present, while libdb2.so.1 is missing.
You can verify the dependencies using the ldd command:
For me, the issue was caused by a missing IBM Data Server Driver directory. IBM_DB_LIB was pointing to a non-existent directory:
Shell
1
2
3
4
5
$set|grepIBM
IBM_DB_DIR=/tmp/dsdriver/.
IBM_DB_HOME=/tmp/dsdriver/.
IBM_DB_INCLUDE=/tmp/dsdriver/./include
IBM_DB_LIB=/tmp/dsdriver/./lib
Reinstalling the Data Server Driver restored the libdb2.so.1 and eliminated the error.
(If you run into this issue with different libraries, you will likely need to examine your LD_LIBRARY_PATH environment variable and use the ldconfig command to reload any changes.)
Do you ever need to kick off a long-running command while SSHed to a server, but be able to disconnect and reconnect at will? You can do this with screen.
Before doing anything, start a screen session:
Shell
1
screen
When you’re ready to put your work on hold, detach the screen:
Shell
1
screen-d
If you have a long-running command running, you can detach that screen from a different shell session by specifying the process id:
Shell
1
2
3
4
# look up the process id
psaux|grepSCREEN
# detach that screen
screen-d<my_process_id>
You can now disconnect from the server safely.
When you reconnect, you can also reconnect to your screen session:
I ran into this error when running ec2-upload-bundle:The specified bucket is not S3 v2 safe (see S3 documentation for details)This was due to uppercase letters or underscores. Later I also ran into an issue with periods in bucket names which showed up as this error message:ERROR: Error talking to S3: Server.AccessDenied(403): Access DeniedHere is an easy command to sanitize the bucket names:
By default, Bash treats uninitialized variables the same way as Perl — they are blank strings. If you want them treated more like Python, you can issue the following command in your bash script:
Shell
1
set-u
You will then start seeing warning messages like the following:
1
./my_script.sh:line419:FOO_BAR:unbound variable
Note that this mean you can’t check for the non-existence of environment variables with a simple [[ -z “$ENVIRONMENT_VARIABLE” ]]. Instead, you could do something like the following: