To avoid using an outdated version of openssl
, it might be a good idea to upgrade it first. The easiest way is to run in a terminal
brew install openssl
As a result instead of openssl
you will need to use /usr/local/opt/openssl/bin/openssl
.
Let’s check a newly installed version
/usr/local/opt/openssl/bin/openssl version
Output:
OpenSSL 3.0.5 5 Jul 2022 (Library: OpenSSL 3.0.5 5 Jul 2022)
The CA certificate is used to verify an authenticity of other certificates during secure communication.
Let’s create two directories named keys
(to store cryptographic keys) and certs
(to store certificates) with the appropriate permissions
mkdir keys certs && chmod og-rwx keys certs
Create a trusted root certificate authority (CA):
/usr/local/opt/openssl/bin/openssl req -new -days 365 -x509 -nodes \
-subj "/CN=Your Company Root CA" \
-keyout keys/ca.key \
-out certs/ca.crt
/C=CN/ST=GD/L=SZ/O=Your Company, Inc./CN=Your Company Root CA
-subj
parameter within the command and pass all these arguments in the interactive mode.Copy a certificate authority’s (CA) certificate (ca.crt
) from the certs
directory to a PostgreSQL configuration directory:
mkdir pgconf && cp certs/ca.crt pgconf/ca.crt
The following code generates a server key and a certificate signing request (CSR), has the CSR signed by the root CA, and adds the server key and certificate to the pgconf
directory with the appropriate permissions:
/usr/local/opt/openssl/bin/openssl req -new -nodes -out server.csr \
-subj "/CN=postgres" \
-keyout pgconf/server.key
CN
(Common Name) field should match the hostname of the server.SAN
) instead of CN
.Now, you need to create server certificate with the appropriate EKU
(Extended Key Usage) and SAN
based on your pgconf/server.key
file, e.g.:
/usr/local/opt/openssl/bin/openssl x509 -req -in server.csr -days 365 \
-CA certs/ca.crt -CAkey keys/ca.key -CAcreateserial \
-out pgconf/server.crt \
-extfile <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=IP:127.0.0.1,DNS:localhost,DNS:postgres\nextendedKeyUsage=serverAuth")) \
-extensions SAN
Note that extendedKeyUsage
says how a certificate can be used:
clientAuth
means it can be used to authenticate a client, i.e. authentication by client certificate when doing mutual authentication.serverAuth
means it can be used to authenticate a server.Let’s remove currently unnecessary server.csr
file
rm server.csr
Set the TLS specific settings in postgresql.conf
:
ssl = on # this enables TLS
ssl_cert_file = '/pgconf/server.crt' # this specifies the server certificate
ssl_key_file = '/pgconf/server.key' # this specifies the server private key
ssl_ca_file = '/pgconf/ca.crt' # this specific which CA certificate to trust
Let’s explicitly lock down the configuration and TLS-related files:
chmod og-rwx pgconf/*
Now is the moment to configure a client, as failing to do so will prevent anyone from accessing this environment.
/usr/local/opt/openssl/bin/openssl req -new -nodes \
-subj "/CN=user1" \
-out client.csr \
-keyout keys/client.key
Note that the CN
for the client certificate must match the username of the client in the database. For example, if I created a user named user1
, then the CN
value must also be user1
.
Let’s lock down the keys files:
chmod og-rwx keys/*
Generate a certificate with an EKU clientAuth
and SAN
:
/usr/local/opt/openssl/bin/openssl x509 -req -in client.csr -days 365 \
-CA certs/ca.crt -CAkey keys/ca.key -CAcreateserial \
-out certs/client.crt \
-extfile <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nkeyUsage=digitalSignature\nextendedKeyUsage=clientAuth\n")) \
-extensions SAN
rm client.csr
You can use environment variables to specify the options:
# the first parameter specifies which TLS mode to use to connect
export PGSSLMODE="verify-full"
# the following two parameters point to the client key/certificate
export PGSSLCERT="`pwd`/certs/client.crt"
export PGSSLKEY="`pwd`/keys/client.key"
# this parameter points to the trusted root CA certificate
export PGSSLROOTCERT="`pwd`/certs/ca.crt"
See docs on environment variables for details.
Now, attempt a connection using only the certificate, without providing a password:
psql -h localhost -p 5432 -U user1 postgres
Error: ca md too weak
Solution: Update your openssl, for ex., use brew install openssl
on macOS and then /usr/local/opt/openssl/bin/openssl req -x509 -nodes...
.
To determine a path of the openssl executable on your system, run
$ which openssl
/usr/bin/openssl
Before (on macOS):
openssl version
Output: LibreSSL 2.8.3
After:
/usr/local/opt/openssl/bin/openssl version
Output: OpenSSL 3.0.5 5 Jul 2022 (Library: OpenSSL 3.0.5 5 Jul 2022)
Error: private key file "keys/client.key" has group or world access; file must have permissions u=rw (0600) or less if owned by the current user, or permissions u=rw,g=r (0640) or less if owned by root
Solution: Set an appropriate permission and ownership rights for your private key file.
Error: pq: certificate authentication failed for user "<user_name>"
Solution: If a certificate was generated with an EKU’s serverAuth
, it should be assigned to a server certificate. If the certificate was generated with an EKU’s clientAuth
, it should be assigned to a client certificate.
ulimit
setting on macOS, but first let’s obtain the current limit of file descriptors via ulimit -n
.
In case this value has not been changed before, a maximum number of open files
most likely will be 256
.
To increase this setting execute
ulimit -n 12288
where 12288
– a desired value.
However keep in mind that ulimit
changes the limit only for current session. So put this command to your ~/.bash_profile
file:
echo 'ulimit -n 12288' >> ~/.bash_profile
In other words,
There are several ways to work around this problem.
If you’re going to be transferring files between Mac’s and PC’s use exFAT. The macOS Mojave supports exFAT file format and since Windows does too, converting an NTFS drive to exFAT may solve the problem of accessing the files it contains on both platforms.
If it’s your case, read this
However you will lose all the data, and in case you forget to backup first, it will be gone forever.
The macOS includes experimental support for writing to NTFS drives. However, it’s off by default and requires some messing around in the terminal to enable it.
If you want to take the risk and try them out, read the following tutorial
This solution could potentially cause problems with your NTFS file system, so use it with caution.
Last but not least, there are third party paid drivers that allow Mac users to read, write and access NTFS formatted USB drives without reformatting the drive with exFAT or using of experimental features.
100
requests in total with 10
concurrent requests to example.com
.
ab -n 100 -c 10 http://example.com/
Note! ApacheBench (ab) is installed on macOS by default.
Output will contain a lot of useful information. However firstly it’s worth paying attention to the following values:
The -H
flag allows you to append extra headers to the request:
ab -n 100 -c 10 -H "Accept-Encoding: gzip,deflate" http://example.com/
The argument is typically in the form of a valid header line, containing a colon-separated field-value pair (ex., "Accept-Encoding: gzip,deflate"
).
The -r
flag means don’t exit if it gets an error:
ab -n 100 -c 10 -r http://example.com/
To make POST requests with a specific file used as the POST data, run the following command:
ab -n 100 -c 10 -p data.json -T application/json http://example.com/
The -T
flag allows to specify the content type header like application/json
. Default is text/plain
.
Use watch
to keep on firing ab
requests at an endpoint. Notice that watch
isn’t available by default on macOS, but can be easily installed with Homebrew:
brew install watch
and run
watch -n 1 ab -n 100 -c 10 http://example.com/
setCustomValidity()
method.
Here’s how the error message will look in the Google Chrome browser when trying to send a form without selecting a checkbox:
HTML code:
<!DOCTYPE HTML>
<html>
<head>
<title>At least one checkbox must be selected</title>
<meta charset="utf-8">
</head>
<body>
<form id="sectionForm" method="post">
<h3>Please select at least one item</h3>
<p><input type="checkbox" name="section" value="sports">Sports</p>
<p><input type="checkbox" name="section" value="business">Business</p>
<p><input type="checkbox" name="section" value="health">Health</p>
<p><input type="checkbox" name="section" value="society">Society</p>
<p><input type="submit" value="Submit"></p>
</form>
<script src="script.js"></script>
</body>
</html>
A content of the script.js
file:
(function() {
const form = document.querySelector('#sectionForm');
const checkboxes = form.querySelectorAll('input[type=checkbox]');
const checkboxLength = checkboxes.length;
const firstCheckbox = checkboxLength > 0 ? checkboxes[0] : null;
function init() {
if (firstCheckbox) {
for (let i = 0; i < checkboxLength; i++) {
checkboxes[i].addEventListener('change', checkValidity);
}
checkValidity();
}
}
function isChecked() {
for (let i = 0; i < checkboxLength; i++) {
if (checkboxes[i].checked) return true;
}
return false;
}
function checkValidity() {
const errorMessage = !isChecked() ? 'At least one checkbox must be selected.' : '';
firstCheckbox.setCustomValidity(errorMessage);
}
init();
})();
Browser console output:
> 0.1 + 0.2
0.30000000000000004
> 0.1 * 0.2
0.020000000000000004
> 16.08 * 100
1607.9999999999998
> 0.1.toFixed(20)
"0.10000000000000000555"
> 9999999999999999
10000000000000000
Don’t get me wrong, this is certainly not a problem of the language itself. The same thing happens in Java, C, PHP, Ruby, etc. If you are interested in the details, please read more in this article.
Below you will find the simplest solutions that allow to “fix” this inaccuracy.
Let’s use the toPrecision method to format a number to a specified precision.
// Pedro Ladaria's solution
function strip(number) {
return (parseFloat(number.toPrecision(12)));
}
Browser console:
> strip(0.1 + 0.2);
0.3
> strip(0.1 * 0.2);
0.02
> strip(16.08 * 100);
1608
Let’s format a number using fixed-point notation into a string with 2 (up to 20) digits after the decimal point using the toFixed method.
Browser console:
> (0.1 + 0.2).toFixed(2)
"0.30"
> (0.1 * 0.2).toFixed(2)
"0.02"
> (16.08 * 100).toFixed(2)
"1608.00"
It’s not hard to get a number as a return value. For instance,
> parseFloat((0.1 + 0.2).toFixed(2))
0.3
php -v
or can see what versions of PHP are installed with
brew list | grep php
Maybe it’s worth cleaning up some of the old packages from brew. It’s up to you.
Make sure brew is up to date:
brew update
brew upgrade
Let’s finally install 7.2 version of PHP
brew install php@7.2
If you need to have this version of PHP first in your PATH
run the following command:
echo 'export PATH="/usr/local/opt/php@7.2/bin:$PATH"' >> ~/.bash_profile
echo 'export PATH="/usr/local/opt/php@7.2/sbin:$PATH"' >> ~/.bash_profile
source ~/.bash_profile
And the result?
php --version
Where is a php.ini file?
Your .ini file is located in /usr/local/etc/php/7.2/php.ini
. To check just type
php --ini
How to install extensions?
PHP extensions have been removed and now should be installed from PECL
:
pecl install xdebug
npm install
xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory'/Library/Developer/CommandLineTools' is a command line tools instance
then to fix it try
Xcode
- go to the AppStore and download the Xcode.xcode-select
developer directory to the appropriate directory from within Xcode.app
. To do this, runsudo xcode-select -s /Applications/Xcode.app/Contents/Developer
$ echo $PATH
Output: /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
Create a symbolic link
$ ln -s "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl" /usr/local/bin/subl
To open the entire current directory
$ subl .
$ brew install awscli
See more http://www.chrisjmendez.com/2017/02/18/aws-installing-aws-client-using-homebrew/
$ brew install python3
$ python3 --version
$ sudo mkdir /usr/local/Frameworks
$ sudo chown $(whoami):admin /usr/local/Frameworks
$ brew link python
Error: pip3: command not found
$ brew postinstall python3
$ pip3 --version
URL: https://docs.aws.amazon.com/cli/latest/userguide/cli-install-macos.html
]]>